AT 经典90题(001-030)
1.Yokan Party
不难考虑到二分答案,check 函数只需使用贪心,如果当前段能选就选即可,最后判断段数是不是大于等于 \(k+1\)。
2.Encyclopedia of Parentheses
考虑暴力枚举每一位,然后线性判断括号串是否合法,把合法的括号串排个序输出即可。
判断方法:初始 sum 为 \(0\),遇到左括号 sum 加上 \(1\),否则减去 \(1\)。如果某一时刻 sum 为负数或者最终的 sum 不为 \(0\) 则不合法;否则合法。
3.Longest Circular Road
不难发现一棵树加一条边会且仅会产生一个环,考虑这个环一定基于一条极长的链,而最长的链就是树的直径。所以这题求的就是树的直径长度加上 \(1\)。
4.Cross Sum
考虑开两个桶分别记录某一行的和以及某一列的和,然后加到一块减去自己即可。
5.Restricted Digits
不难想到动态规划,但是朴素版本只能通过子任务 \(1\)。
我们设 \(f_{i,j}\) 表示长度为 \(2^i\) 的模 \(b\) 余 \(j\) 的数有多少个。从 \(f_i\) 向 \(f_{i+1}\) 转移可以看作把两个长度为 \(2^i\) 的部分拼到一起。
设 \(ne\) 为模 \(b\) 余 \(j\) 的一个数放在高位,模 \(b\) 余 \(l\) 的一个数放在低位拼出来的数模 \(b\) 得到的结果。于是有转移 \(f_{i+1,ne}\leftarrow f_{i+1,ne}+f_{i,j}\times f_{i,l}\)。
因为 \(n\) 是由若干个 \(2\) 的次方拼起来的,所以答案统计就是若干个 \(f\) 拼起来。所以设 \(res_{i,j}\) 表示已经解决了最低的 \(i\) 位,当前数模 \(b\) 余 \(j\) 的方案数
具体地,当 \(n\) 的二进制下第 \(i\) 位为 \(1\) 时,有转移 \(res_{i+1,ne}\leftarrow res_{i,j}\times f_{i,l}\),这里变量的含义同上。否则 \(res_{i+1,j}=res_{i,j}\)。
最后答案就是 \(res_{63,0}\)。
6.Smallest Subsequence
比较显然的贪心,考虑找出当前字典序最小的字母使得从这个字母出发能凑出 \(k\) 个字母,然后选取当前位置后面的最靠前的这个字母并更新当前位置即可。
7.CP Classes
使用一个 set 维护所有数,同时加入极大值和极小值。设 pre 为当前查询数的前驱,nxt 为当前查询数的后继。答案即为 \(\min(x-pre,nxt-x)\)。
8.AtCounter
考虑一个简单的动态规划,\(f_{i,j}\) 表示前 \(i\) 位匹配给定串前 \(j\) 位方案数。初始 \(f_{0,0}=1\)。
转移显然:\(f_{i,j}\leftarrow f_{i-1,j}\),当该串第 \(i\) 位与给定串第 \(j\) 位相同时,有转移 \(f_{i,j}\leftarrow f_{i,j}+f_{i-1,j-1}\)。最后答案 \(f_{n,7}\)。
9.Three Point Angle
首先我们枚举一个点,把它看作角的顶点。接下来把这个点看成原点,找出所有其他点和 \(x\) 轴正半轴上面的角,存到 \(e\) 数组里。
接下来枚举所有 \(e\) 中的所有角度,假设当前枚举的角度为 it,我们的目标为 it 加上 \(180\) 度(如果超过周角则减去一个周角),假设其为 tar,二分出 tar 的前驱和后继尝试更新答案即可。
10.Score Sum Queries
考虑开两个前缀和数组,分别存 \(1,2\) 班的前 \(i\) 个人分数和。每次询问答案即为两个数组的 \(s_r-s_{l-1}\)。
11.Gravy Jobs
设 \(f_{i,j}\) 表示前 \(i\) 个任务在前 \(j\) 时间里能获得的最大收益。于是有转移 \(f_{i+1,j}\leftarrow f_{i,j}\)。
当 \(j+c_{i+1}\le d_{i+1}\) 时,还有转移 \(f_{i+1,j+c_{i+1}}\leftarrow \max(f_{i+1,j+c_{i+1}},f_{i,j}+s_{i+1})\)。
答案即为 \(f_{n,i}\) 的最大值。
12.Red Painting
考虑使用并查集维护两个位置是否连通即可。每次把一个点染红即为尝试与周围四个点相连。
13.Passing
考虑从 \(1\) 和 \(n\) 分别出发跑最短路,设其数组为 \(f,g\),对于点 \(i\) 的答案即为 \(f_i+g_i\)。
14.We Used to Sing a Song Together
考虑将 \(a,b\) 升序排列,答案即为对应位置的差的绝对值之和。
15.Don't be too close
考虑求答案为 \(i\) 时选了 \(j\) 个数的方案数。其实就是在 \(n\) 个数中挖掉 \((i-1)\times (j-1)\) 个数然后选 \(j\) 个数。于是 \(i\) 的答案就是\(\displaystyle\sum_{j=1}^{\lceil\frac{n}{i}\rceil}\binom{n-(i-1)\times (j-1)}{i}\)。
16.Minimum Coins
由于答案不超过 \(9999\),所以我们暴力枚举 \(a,b\) 的个数,计算 \(c\) 的个数,尝试更新答案即可。
17.Crossing Segments
考虑正难则反。考虑两条线段什么情况下无交:
-
其中一个点重合。
-
\(l_1<r_1<l_2<r_2\)。
-
\(l_1\le l_2<r_2\le r_1\)。
分别计算这三种情况然后减掉即可。
18.Crossing Segments
数学题,只需要通过转的角度算出来当前坐标然后用正切值算角度即可。
具体地,公式为:
-
\(x=0\)。
-
\(y=-\frac{l}{2}\times \sin (\frac{2\times e}{t}\times \pi)\)。
-
\(z=\frac{l}{2}-\frac{l}{2}\times \cos(\frac{2\times e}{t}\times \pi)\)。
然后简单计算一下就得到了最终直角三角形的两条直角边,直接用正切值算角度即可。
19.Pick Two
考虑动态规划。设 \(f_{i,j}\) 表示删除区间 \([i,j]\) 的最小代价。显然区间长度为偶数才有意义。于是考虑转移。
首先初始化所有 \(j=i+1\) 的 \(f\) 数组。
\(\forall k\in[i,j]\),\([i,k]\) 长度为偶数时有转移 \(f_{i,j}\leftarrow \min(f_{i,j},f_{i,k}+f_{k+1,j})\)。
还有转移 \(f_{i,j}\leftarrow \min(f_{i,j},f_{i+1,j-1}+|a_i-a_j|)\)。
20.Log Inequality
转化形式,比较 \(a\) 和 \(c^b\) 的大小即可。注意 \(13^{17}<9\times 10^{18}\)。
21.Come Back in One Piece
\(x\) 和 \(y\) 互相能到达的充要条件是 \(x,y\) 属于同一个强连通分量。于是跑一个 tarjan,设 \(siz_i\) 表示第 \(i\) 个强连通分量里的点数,共有 cnt 个强连通分量。答案就是 \(\displaystyle \sum_{i=1}^{cnt}(\frac{siz_i\times (siz_i-1)}{2})\)。
22.Cubic Cake
考虑立方体一定越大越好,考虑最大棱长一定是 \(d=\gcd(a,b,c)\)。于是答案就是 \(\frac{a}{d}-1+\frac{b}{d}-1+\frac{c}{d}-1\)。
23.Avoid War
首先朴素 dp 是无法通过的。我们考虑优化。不难发现如果我们从上到下,从左到右 dp,影响每个位置的地方只有 \(m+1\) 个。于是我们设 \(f_{i,j,k}\) 表示第 \(i\) 行第 \(j\) 列,前 \(m+1\) 格的放置状态为 \(k\) 的方案数。
转移显然,假设这个位置放 \(0\) 后这位及以前前 \(m+1\) 位的状态为 \(v_0\),放 \(1\) 后这位及以前前 \(m+1\) 位的状态为 \(v_1\),\((x,y)\) 为 \((i,j)\) 的下一格。有转移 \(f_{x,y,v_0}\leftarrow f_{x,y,v_0}+f_{i,j,k}\)。当 \((i,j)\) 可以放置时,有转移 \(f_{x,y,v_1}\leftarrow f_{x,y,v_1}+f_{i,j,k}\)。
但是这个东西仍然无法通过。注意到合法的状态不会太多,所以我们只用合法的状态进行转移即可,即把上面的 \(k,v_0,v_1\) 离散化一下。这里合法的状态数量大约是斐波那契数列的第 \(m\) 项。
24.Select +/- One
设最少需要 \(cnt\) 次还原,合法当且仅当 \(cnt\le k\) 且 \(cnt\bmod 2=k\bmod 2\)。
25.Digit Product Equation
考虑搜索剪枝。先枚举答案的位数,然后枚举每一位,不难发现我们只关心乘积,也就是说数字顺序不重要,所以我们要求数字降序。然后判断当前乘积加上 \(b\) 是否可能是当前数的数字的其中一个排列即可。
26.Independent Set on a Tree
考虑把点按深度的奇偶性划分到两个集合内,哪个集合内的点数量不少于一半,就用哪个集合内的点的前 \(\frac{n}{2}\) 个。
27.Sign Up Requests
使用一个 map 看这个字符串之前是否出现过即可。
28.Cluttered Paper
发现坐标范围非常小,只需要用二维差分修改最后用二维前缀和算答案即可。
29.Long Bricks
考虑使用线段树维护区间最大值,修改区间的值即可。
30.K Factors
考虑搜索剪枝,每次尝试乘上一个质数,不难发现最多乘 \(23\) 次,于是我们暴力乘一个质数即可。这里可以通过要求质数是不降的来进行更好的剪枝。

浙公网安备 33010602011771号