调整一下排版。此外对于比较简单的题目,我就不写问题描述了。
——————
Codeforces Round 998 (Div. 3)

用时:7 分钟 - 13 分钟 - 35 分钟 - 12 分钟 - 38 分钟,共 1 小时 45 分
——————
A 题:暴力
思路:暴力枚举所有可能的 v[2],寻找最大答案。
难点在于枚举的上下限选择——我们必须选择上下限 [L, R],使得所有位于 (-∞, L) ∪ (R, ∞) 的 v[2] 对应的答案都是最小值 0。
这里我选择的是 [-201, 201]。
代码:

——————
B 题:数学
问题描述:有 nm 张牌,每张牌上面都有一个范围在 [0, nm) 中的数字且不存在两张数字相同的牌。同时,有 n 个玩家,每个人都分配到 m 张牌,共进行 m 个回合,每回合每人都出一张牌,而且必须按照 0, 1, 2, ..., mn - 1 的次序出牌,如果无法出牌则游戏结束。
每回合出牌的先后顺序是固定的,即某人在某回合是第 k 个出牌的,那么他在其他回合也必须是第 k 个出牌。问能否找到一种出牌的先后顺序,使得每个玩家都能出完其手中的所有牌。
思路:显然,拥有 “0” 的玩家必须同时拥有 "n"、“2n”、……、“(m-1)n”。一般地,拥有 "x" 的玩家,其所有牌上的数字对 n 取模都必须等于 x 对 n 取模的结果。如果这一条件对于所有玩家都成立,那么可行的出牌顺序就是 “拥有 '0' 的玩家 - 拥有 '1' 的玩家 - ... - 拥有 'n-1' 的玩家 ”。
代码:

——————
C 题:博弈(终于做出一道博弈题了 😀)
问题描述:黑板上有 n 个数字,每一回合 A 和 B 依次选择两个数字 a, b,然后将所选择的数字从黑板上擦掉,若 a + b = k,则分数加一。A 的目标是最小化分数,B 的目标是最大化分数。如果 A、B 都按照最优策略行动,问游戏结束(黑板上没有数字)时的分数是多少。
思路:我们可以把这个问题抽象为无向图,其中结点为数字,如果 u,v 之间有一条边,则说明 u + v = k。使用初始的 n 个数字建图,得到类似下图的结果:

其中结点右下方的数字代表该结点的出现次数。
注意每个结点的度最多为 1,这是因为对于固定的 u,和 u 配对的数字 k - u 是唯一的。
我们发现,结点可以分为两类:第一类度为 0 ,第二类度为 1 。
对于玩家 A 来说,应当先消耗第一类结点。如果第一类结点的数量为奇数,则 B 将被迫消耗一个第二类结点。当所有第一类结点都被消耗完后,才能开始消耗第二类结点。考虑互相连接的两个结点 (u, v),它们对分数的贡献为 min(cnt[u], cnt[v]),因此我们只需要遍历所有的第二类结点,计算出它们的贡献,然后根据第一类结点的数量是否为奇数进行分类讨论,得到最终分数。
备注:看了官方题解,实际上不用做这么复杂。
代码:

——————
D 题:贪心
问题描述:给你一个整数数组,对于相邻的元素 a, b,每次操作可以将它们变成 a - min(a, b), b - min(a, b),问能否经过任意次数的操作得到不下降数组。
思路:注意到操作并不改变相邻元素的相对大小。我们可以从左往右处理所有相邻元素,设左边的元素为 a,右边的元素为 b,若 a <= b,则将它们变成 0, b - a,这样后面的元素就更容易满足不下降的条件;如果 a > b,则无解,因为之前的元素已经无法再减小了,减小 a, b 又不改变相对大小,减小后续的元素只会让 b 更小或者不变。

——————
E 题:连通分量、贪心
问题描述:给你两张结点数量相同的简单无向图 F、G,每次操作可以删除 F 中的一条边或者添加一条边,且需要保持简单图的性质,问最少需要多少次操作使得:
对于 G 中的任意两个节点 u, v,若存在从 u 到 v 的路径,则 F 也存在从 u 到 v 的路径;
若不存在从 u 到 v 的路径,则 F 也不存在从 u 到 v 的路径。
思路:首先用并查集或者 DFS 计算出 G 的连通分量。
然后扫描 F 的所有边,将连接两个不同连通分量的边去除,去除的边数记为 op1,此时能保证 “若不存在从 u 到 v 的路径,则 F 也不存在从 u 到 v 的路径”。
最后用并查集或者 DFS 计算出 F 的连通分量,根据 G,将 F 的连通分量进行分类 。若 F 中的连通分量 A1、A2、....、Ak 中的所有结点在 G 中属于同一个连通分量,则它们应被分到同一类。
统计每一类的连通分量个数 x,最少需要连接 x - 1 条边使它们变成单个连通分量,因此这一类对答案的贡献为 x -1。记所有类对答案的贡献为 op2。
答案为 op1 + op2。
代码:
