退役选手的 NOIP 2018 普及组题解 QAQ
题面
数据
下载地址:NOIP 2018 普及组测试数据
标题统计
Description
输入一行可能带空格的字符串,求除空格外有多少个字符。
Solution
使用 $\text{scanf}$ 或 $\text{cin}$ 读入每个字符串(不包含空格),然后统计字符串的长度之和即可。
时间复杂度:$O(|s|)$
Code
1 |
|
龙虎斗
Description
在数轴上有 $n$ 个点,第 $i$ 个点的位置为 $i$,权值为 $c_i$。现在给第 $p_1$ 个点的权值增加 $s_1$,你必须再给一个点的权值增加 $s_2$ 满足对于给定的一个坐标为 $m$ 的点,使得 $\sum_{i=1}^n c_i(i-m)$ 的绝对值最小。
Solution
首先,我们直接把 $s_1$ 位工兵增加到第 $p_1$ 号兵营,设 $s=\sum_{i=1}^n c_i(i-m)$
我们考虑如果在第 $p_2$ 的位置增加 $s_2$ 位工兵,那么可以得到 $s’=s+s_2(p_2-m)$。我们只需要求出使得 $s’$ 的绝对值最小的 $p_2$。我们可以直接枚举 $p_2$,在 $O(1)$ 的时间内计算出 $s_2$,更新答案的过程中要注意字典序最小的要求。
时间复杂度:$O(n)$
Code
1 |
|
摆渡车
Description
有 $n$ 名同学在同一地点等车去同一目的地,第 $i$ 个人在第 $t_i$ 分钟开始等车。现在只有一辆车可以载人(车的容量可以视为无限大),往返一趟需要的时间为 $m$ 分钟。这辆车需要把所有同学都送到目的地。如果这辆车能在任何时间出发,回到等车地点后又可以即刻出发,求出这些同学的等车时间之和最小为多少。
Solution
引理:对于每个乘客,如果他开始等待的时刻为 $t$,那么搭载他的车的发车时间 $t_0\in [t,t+m)$。
证明:如果存在一种发车时间 $\geqslant t+m$,那么发车时间一定可以提早若干个 $m$ 使得 $t_0$ 到达 $[t,t+m)$。这样不会影响其他 $\geqslant t+m$ 的发车时间,不会干扰后面的人等车。
我们考虑 $\text{DP}$ 状态设计:$f[i][j]$ 表示搭载了前 $i$ 个人,搭载第 $i$ 个人的摆渡车的发车时间为 $t_i+j$ 的最小等候时间总和。朴素的转移方程为:
其中 $\text{cost}(i,j,k)$ 表示第 $i\sim j$ 个人在 $k$ 时间乘车的等候时间总和。注意转移过程中有 $t_i+j\geqslant t_k+p+m$(当前这趟车比上一趟车至少晚 $m$)的限制!
这个式子直接计算是 $O(n^3m^2)$的,接下来考虑转移如何优化。上述式子中,我们通过对 $t_i$ 做前缀和可以 $O(1)$ 计算出 $cost$ 的值。我们再记 $g[i][j]=\min_{0\le j<m}f[i][j]$(这个前缀 $\min$ 可以在转移过程中维护),转移方程化为 $f[i][j]=\min_{0\le k<i}\{g[k][x]+\text{cost}\}$,其中 $x=\min(m-1,t_i+j-t_k-m)$ 且 $x\geqslant 0$,时间复杂度优化为 $O(n^2m)$ 。
时间复杂度:$O(n^2m)$
Code
1 |
|
对称二叉树
Description
一棵二叉树被称为对称二叉树当且仅当:这是一棵二叉树,将这棵树所有节点的左右子树交换,新树和原树的结构和点权完全相同。
现在给定一棵二叉树,希望找出它的一棵子树,使得该子树为对称二叉树,且节点数最多。
Solution
记 $u$ 的左右儿子分别为 $\text{lson}_u$ 和 $\text{rson}_u$。对于以 $u$ 为根的一棵子树,如果它是对称的那么必须满足:
- $\text{lson}_u$ 和 $\text{rson}_u$ 是对称的。
- 对于每一对左右儿子 $x,y$,必须满足 $\text{lson}_x$ 和 $\text{rson}_y$ 是对称的、$\text{rson}_x$ 和 $\text{lson}_y$ 是对称的。
我们可以对于每个节点暴力判断是否满足条件。判断的过程中,我们可以使用一些剪枝:左右儿子的大小、权值和等必须相同。
复杂度证明:每次判断子树 $x$ 和 $y$ 是否对称时,复杂度为 $O(\min(\text{size}_x,\text{size}_y))$,如果一个点能往上继续产生贡献,那么大小至少乘以 $2$,总复杂度即为 $O(n\log n)$
时间复杂度:$O(n\log n)$
Code
1 |
|