NWERC 2020 题解
和主席 VP 玩了一下,打了 8 题,只能说主席太强了。
比意想中的要简单一点,而且有两道随机化题。
A - Atomic Energy
考虑一个暴力 dp:设 \(f(i)\) 表示中子数为 \(i\) 的原子可以产生的最小能量。那么在 \(M\) 以内的 dp 值是可以 \(O(M^2)\) 预处理的。
注意到 \(k\) 很大,而 \(n\) 很小。考虑背包问题的一个假贪心:每次选“性价比”小的。一般情况下,组合起来可能不是最优的。然而当我们的容量很大时,我们可以在一个限度内施展这样的贪心。由于每个物品的体积都比较小,所以“组合更优”不会在大范围出现。
对于本题,设阈值 \(M=n^2\)(这个值不一定最优,是平方算法可以承受的较大值)。然后 \(O(M^2)\) 预处理小范围的 dp,对于 \(k\) 很大的情况可以先一直一个性价比最小的,直到在 \(M\) 以内直接拼上 dp 值。这样复杂度是 \(O(M^2+q)\) 的。
C - Contest Struggles
签到。答案为 \((d\times n - k \times s) \div (n-k)\)。在 \([0,100]\) 内合法。
D - Dragon Balls
限制很宽,有很多种做法。
这里是个好写的做法:考虑随机一个点,算出距离 \(d^2\)。考虑这个 \(d^2\) 肯定是根据勾股定理算出来的,那么我们只要得到 \(a,b\) 两个整数满足 \(a^2+b^2=d^2\),然后在随机的那个点周围 \(8\) 个方向上都测一遍。
实测这样得到的 \((a,b)\) 最多三十多组,并且随机情况组数很少。所以一千次是绝对足够的。
\(d^2\) 可以达到 \(10^{12}\) 级别,但 \(a, b\) 只有 \(10^6\) 级别,所以不会有超时问题。
E - Endgame
首先考虑一个简单问题:给定始终点 \(A, B\),判断 \(A\) 能否操作两次吃掉 \(B\)。这个比较简单,用一个 set 记录所有操作,然后枚举第一次操作,尝试配对所求第二次操作。这样可以 \(O(n\log n)\) 完成一次判断。当然可以强行优化到更快。
实现上面从操作之后可以判断 Alice 是否能赢。但是之后是否存在 tie 的位置似乎没什么好办法,对于 \(n\) 比较小我们可以逐一测试,但是肯定是过不了的。
我们发现一个很离谱的事情就是,棋盘是 \(n \times n\) 的,而操作种类是 \(n\) 个。为什么都是 \(n\)?\(n\) 个操作可以拼出 \(O(n^2)\) 个位置,但绝(除了 \(n=2,3\) 的小数据)不会占满整个棋盘,而且冷静分析有相当一部分位置都是空的。
我们考虑随机化:每次随机一个点,判断是否可以 tie。由于随机很多次都点不到的概率是极低的,所以很快就能找到解。
官方题解指出空位的规模是 \(n^2/2\),因此期望两次出解。但是我不知道怎么来的,一个较简单的 \(n^2/4\) 的构造是 \((1, 0), (2, 0), \cdots, (n/2, 0), (0, 1), (0, 2), \cdots, (0, n/2)\)。
F - Flight Collision
要求快速模拟整个过程,实际上只需要我们正确模拟就行了,因为每个坠毁时间只会在一对飞机上发生一次。
要正确模拟,只要让一个个坠毁事件按时间顺序发生,显然这样不会出现任何跨越的情况,其间飞机间的相对位置也不会改变。
考虑用 set 或链表维护存活的飞机,用堆维护接下来可能发生的坠毁事件。复杂度 \(O(n\log n)\)。
G - Great Expectations
完全不会这种带环的期望题。
从容错的角度考虑状态设计:我们需要比 \(r\) 小,而 \(n\) 是不得不消耗的花费,那么最多可以承受 \(r-n-1\) 的失误代价和。设 \(f(i,j)\) 表示将要到达第 \(i\) 个关卡,以及消耗了 \(j\) 的容错,走到终点需要的期望时间。
可以发现的是,如果真的要重开,那一定是刚刚失误被卡了一下的那个时刻。那么有方程:
其中 \(f(0,0)\) 是起点的期望,代表重开,同时也是我们要求的答案。
我们试一个答案 \(v\),并在方程中用 \(v\) 代替 \(f(0,0)\) 计算,并用最后得到的 \(f(0,0)\) 比较。如果 \(f(0,0)\) 较大说明答案会比 \(v\) 更大,反之同理。我也不知道为什么会这样。
最后二分答案即可。复杂度 \(O((r-n)m \log \text{ans})\)。
H - Hot Springs
把所有数组放到一个数轴上。可以发现,我们从中间位置开始,左右横跳,越跳越远,这样必然可行。
那么我们找到中位数,然后分成两部分,轮流输出即可。
I - Island Tour
考虑 \(O(n^4)\) 暴力,枚举三个人的位置 \(i, j, k\),然后检查每个位置是否都不冲突。如果 \(i, j\) 两个人中 \(j\) 先到某位置 \(p\),那么 \(j\) 离开 \(p\) 的时间不应大于 \(i\) 到达 \(p\) 的时间。
VP 时主席写了个这样的暴力,然后加了个超过时限就输出无解摆烂,结果真的 AC 了。之后猜了猜,如果有解,那么 \(i=1\) 时也必然有解,结果加个 assert 也过了。这玩意也不知道怎么证,也可能是假的。如果有人能给个证明可以在 这里 或者评论区说两句。
但其实靠谱做法非常简单:观察到我们要判的只有 \(O(n^2)\) 种本质不同的位置对,那么只有 \(O(n^3)\) 预处理是否合法即可。最后求解也是 \(O(n^3)\)。
J - Joint Excavation
很好玩的题。官方解法也非常妙。
考虑直接 DFS。DFS 过程中的点我们分为三类:(一)从未访问的点,(二)DFS 栈中的点,以及(三)曾经访问过但不在栈中的点。曾经访问过就是经历过回溯操作的点。
一个神奇的观察:三类点中,(一)类和(三)类间不相邻。具体证明非常显然:考虑 DFS 的过程,如果存在这条边,那么当时不可能直接回溯而会直接进入那个未访问的点。
注意(二)类点刚好可以构成一条点不自交的路径,那么最后在 DFS 中某时刻出现(一)类点和(三)类点数目相同时遍求得了一组解。
K - Keyboardd
检查所有小写字母及空格,把多的输出即可。
本文来自博客园,作者:-Wallace-,转载请注明原文链接:https://www.cnblogs.com/-Wallace-/p/sol-nwerc2020.html