AtCoder Beginner Contest 259 题解
A - Growth Record
分类讨论一下即可。
Code
B - Counterclockwise Rotation
思路很简单,先用 atan2
函数求出初始角度,用勾股定理求出线段长度。
再将初始角加上 \(d\) 度。
最后用三角函数再算一下就好啦 /cy
(这里我因为把 \(360\) 度当成 \(\pi\) 算导致 WA 了好几发QAQ)
Code
C - XX to XXX
首先会发现,\(S\) 的最后一个字符只能跟 \(T\) 的最后一个字符匹配,这启发我们倒着匹配。
同时用 \(i,j\) 两个指针维护,表示当前匹配到了 \(S(i),T(j)\),分两种情况:
-
\(S(i) = T(j)\),匹配成功,\(i \gets i-1,j \gets j -1\)。
-
\(S(i) \neq T(j)\),又可以讨论一下:
-
\(S(i+1)=T(j)\) 且 \(S(i+1)=S(i+2)\) 时,可以在 \(S(i+1)\) 和 \(S(i+2)\) 间再塞一个 \(T(j)\)
-
若不满足以上条件,则匹配失败。
最后再注意一下两个指针是否都走到开头,再判断一下即可。
Code
D - Circumferences
珂以用并查集把所有有交点的圆合并起来,判断起点终点是否在同一个圆的集合即可。
如果两个圆无交点,只有两种情况:
-
相离:圆心间距离大于半径之和
-
包含:圆心间距离小于半径之差
不是这两种情况的话,直接并查集合并即可。
需要注意一下精度问题,开 double
不太合适,所以我用了 long long
,把所有距离都平方一下就好了。
Code
E - LCM on Whiteboard
显然可以枚举每个数,判断其变为 \(1\) 后是否会对 \(\operatorname{lcm}\) 值产生影响。
显然如果这个数的因数里存在一个 \(p_i^{e_i}\),使得 \(e_i\) 是 \(p_i\) 最大的指数且仅出现一次,那么会产生影响。
还有要注意的就是如果一个数改变不了 \(\operatorname{lcm}\),那么原来的 \(\operatorname{lcm}\) 也要计入一次答案。
Code
F - Select Edges
状态很多,一看就是个 DP,但我一开始不知道怎么设状态,感觉贪心也许可行,结果不出意外 WA 了一发。
仔细想一想,其实不难设出状态。
对于一条边 \((u,v)\)(\(u\) 是 \(v\) 的父亲节点),如果选了这条边,在 \(v\) 的子树内,\(d_v \gets d_v -1\),反之 \(d_v\) 不变。
也就是说,对于一个节点 \(v\),它的度数 \(deg\) 只有两种情况:
-
\(deg \le d_v\)
-
\(deg \lt d_v\)
第二种情况下,\((u,v)\) 这条边可选,第一种则不行。
那么状态就显而易见了:
设 \(dp(u,0/1)\) 表示在 \(u\) 节点的子树内, \(deg_u\le d_u(0)\) 和 \(deg_u \lt d_u(1)\) 时,答案的最大值。
如果我们令 \(ans = \sum\limits_{v \in son_u} dp(v,0)\),考虑选一条边 \((u,v,w)\) 产生的贡献:
显然 \(dp(v,0)\) 要变成 \(dp(v,1)+w\),那么对 \(ans\) 会产生 \(dp(v,1)+w-dp(v,0)\) 的贡献。
将所有 \((u,v)\) 的贡献存起来降序排序,贪心地更新 \(ans\) 即可。
Code
G - Grid Card Game
正难则反,显然有贡献的行列上的数和均为正数,把这些行和列全选上,考虑删掉一些。
具体来说,令 \(r_i = \sum\limits_{j=1}^m a(i,j),c_j = \sum\limits_{i=1}^n a(i,j)\)。
先设答案为 \(ans = \sum\limits_{i=1}^n r_i + \sum\limits_{j=1}^m c_j\),再考虑删去重复和不合法的。
对于 \(a(i,j)\),分类讨论:
-
\(a(i,j) \ge 0\),则需删去 \(r_i\) 或 \(c_j\),或者两者皆删去。
-
\(a(i,j) \lt 0\),则需删去 \(r_i\) 或 \(c_j\),或者都删。
这种模型似曾相识,发现我们要让删去的最小,因此考虑使用网络流最小割建模解决。
对所有 \(r_i,c_j\) 建点 \(R_i,C_j\),所有 \(R_i\) 与源点 \(S\) 连边,容量为 \(\max(r_i,0)\)。
同理,所有 \(C_j\) 与汇点 \(T\) 连边,容量为 \(\max(c_j , 0)\)。
对于所有 \((i,j)\),\(R_i\) 和 \(C_j\) 需要连边,边的容量需要讨论一下:
-
\(a(i,j) \ge 0\),边容量即为 \(a(i,j)\)。
-
\(a(i,j) \lt 0\),边容量为 \(INF\),表示这条边无法删去,只能删去 \(r_i\) 或 \(c_j\) 才能不连通。
用 \(ans\) 减去最小割的值即可。
Code
Ex - Yet Another Path Counting
这题是真的一点思路都没有,只知道组合数暴力瞎搞QAQ。
解法貌似也算是根号分治。
显然组合数暴力是 \(O(N^4)\) 的,过不了这道题。
没什么思路,珂以转向思考性质,发现出现 \(N\) 次以上的颜色个数小于 \(N\)。
那么久珂以用类似根号分治的解法了。
对于每种颜色,存下它出现的所有位置。
如果它出现的次数不超过 \(N\),直接跑暴力。
式子有点复杂,不过小推一下就会发现这类情况总体时间复杂度是 \(O(N^3)\) 。
对于出现次数大于 \(N\) 的颜色,跑一遍 \(O(N^2)\) 的 DP 即可。
这部分不过多解释,具体 DP 方式看代码。
显然这类情况总体时间复杂度也为 \(O(N^3)\)。
那么整个算法时间复杂度即为 \(O(N^3)\)。
Code
Summary
第一次 vp ABC,明显感受到自己的不足,大佬们秒切的题我还要慢慢调半天,稍微上点难度就不会写。还是要继续加油啊!