- SamuelXuch's blog
20251016题解
- 2025-10-16 21:30:16 @
T1 减去因子
题意
一开始有一个整数 ,两个人轮流选数,每次可以选择一个当前数字的非 非 的因子,让当前数字减去该因子,不断操作,直到没得选为止,问谁会赢。
思路
我们分下面 种情况讨论:
- 当前的数 n 是个奇数;
- 当前的数 n 是偶数但不是 2 的幂。
- 当前的数 n 是 2 的幂。
- 第 1 种情况:由于 n 是奇数,那么选择的 n 的约数 k 肯定也是奇数(奇数×偶数会产生偶数),而且由于 k∣n 和 k∣k,所以 k∣(n−k),所以 n−k 一定不是 2 的次幂(因为有约数 k),转化为第 2 种情况。
- 第 2 种情况:接下来我们要证明面对这种情况先手是必胜的。由于 n 是偶数但不是 2 的幂,那么一定存在一个奇数非 1 约数 k,考虑让 n 减掉这个 k,就转化为第 1 种情况。而这样循环会在哪一步结束呢?很显然是在第 1 种情况结束,因为第 2 种情况的操作是无论 n 为任意满足条件的值都可以进行的,而第 1 种情况的会在面对质数的时候停止。
至此我们证明了第 1 种情况必败,第 2 种情况必胜。
- 第 3 种情况:n 是 2 的幂时,我们可以减去 使得 n 仍然是第 3 种情况,也可以减去一个其他数使得转化为第 2 种情况。但是第 2 种情况是必胜的,所以不应该转化为第 2 种情况。于是唯一的选择就是对半减。所以 n 是 2 的奇数次幂时必败,n 是 2 的偶数次幂时必胜。
T2 袜子
题意
有 双袜子,第 双由两枚颜色为 的袜子组成。现在丢失了颜色为 的袜子各一枚,于是他决定用剩下的 枚袜子重新组成 双袜子。由颜色为 和 的袜子组成的双袜子的奇异度定义为 ,高桥君希望使奇异度的总和尽可能小。
请计算在最优组合下,奇异度的最小总和是多少。注意,如果 是奇数,会有一枚袜子不被包含在任何双袜子中。
思路
不难发现如果有成对的袜子,互相匹配是最优的,那么就剩下来 只落单的如何匹配。
可以观察到,如果 参与匹配时能找到一个存在的 ,使得 最小,那么将数组排序后, 与 一定相邻。所以,将数组从小到大排序,逐个将 与 的差相加即可。
然而,我们并没有AC。再看一遍题目,可以注意到题目中没有限制 不为奇数,在 是偶数时,这个方式显然最优。但 是奇数,就需要扔掉一只袜子。
扔哪只呢?如果直接逐个枚举,时间复杂度为 ,显然会超时;但如果我们预先将前缀和求出来,求值部分时间复杂度就可降低到 。
设从 开始往后求相邻差的前缀和的数组为 ,从 往前求相邻差的前缀和的数组为 ,如下图:
如果我们要删除的是图中黑色部分,那么剩下的差异和就为e[1] + b[1] + a[4] - a[2]
。
也就是说,如果要删除第 个颜色,当 为偶数时,差异和为b[i - 2] + e[i + 2] + a[i + 1] - a[i - 1]
; 为奇数时,差异和为b[i - 1] + e[i + 1]
。
T3 幻想机器人
题意
走格子
思路
模拟
T4 石头
题意
和 在玩一个取石子的游戏。
刚开始,有 个石子,还有一个长度为 的序列 。
现在,他们要按照以下规则轮流取石子:
-
对于每次操作,他可以选择一个 (),这时他会取走 块石子。
-
当一个人没法取石子时,游戏结束。
现在, 先取石子, 后取石子。他们都想尽可能的最大化他们自己取走的石子数量。
若他们都以最优策略取石子,最后 会取走多少块石子?
思路
博弈论dp,设 表示当前的石子数量为 时,先手能取的最大值。
假设先手 alice 取的是 ,那么石子数变为 ,alice 取完后,此时的先手是 bob,则此时 bob 能取到的最大石子数表示为 ,所以 可以由 转移得到,即 由 转移得到。
时间复杂度:
T5 传感器优化困境
题意
有一种商品的制造需要在工厂流水线经过 的 个步骤,才算完成。
对于每个步骤 ,都有两种处理该步骤的机器 和 可供购买:
-
机器 :每台可处理 个产品,每台价格为 日元。
-
机器 :每台可处理 个产品,每台价格为 日元。
在每个步骤中,两种机器可以购买任意数量(包括零台)。
假设步骤 在引入机器后,可以处理 个需要经过步骤 的产品,我们把这个 定义为步骤 的处理量。
同时将工厂流水线的处理能力定义为所有步骤的处理量中的最小值,即 。
现在问在总预算为 日元的情况下,工厂流水线可达到的最大处理能力是多少。
思路
注意到 和 ,这个数据范围比较小,很可能与时间复杂度有关。
题目要求 的最大值,看到最小值最大,果断二分。于是思路就出来了:二分 ,看能否用 的预算达到。
具体来讲,二分 ,对于第 轮加工,我们要使 ,也就是找到这样的 ,使得 且 。
要想不超过预算,花费就得尽可能少,也就是要使 最小,同时要让 。
这就引出本题的一个结论:第 轮加工的两种机器中,必有一种机器的购入数量少于另一种的单台机器产量。
换句话说,如果你主要购入 ,那么你购入的 的数量少于 。反之亦然。
这是因为,每当你购入 台 或 台 ,你都会获得 的产量。而对于相同的 的产量,为使花费最少,一定只会选择两种方案中更便宜的那一种(也就是 )。所以,当你主要购入 的时候(此时 ),每当你购入 台 ,你都可以将其换成更优的 台 。
那么我们直接在二分里面枚举 或 的数量,取花费最小值即可。
bool check(int x) {
int sum = 0; //达到x生产容量的最小花费
for(int i = 1; i <= n; i++) {
int res = 1e15; //寻找最小花费
for(int j = 0; j < a[i]; j++) {
//枚举主要购买Si时,购入的Ti数量
if(j*b[i] > x) break;
int tmp = x-j*b[i];
res = min(res, j*q[i]+(tmp+a[i]-1)/a[i]*p[i]);
}
for(int j = 0; j < b[i]; j++) {
//枚举主要购买Ti时,购入的Si数量
if(j*a[i] > x) break;
int tmp = x-j*a[i];
res = min(res, j*p[i]+(tmp+b[i]-1)/b[i]*q[i]);
}
sum += res;
}
return sum <= X;
}