1 条题解
-
0
题目题解
问题理解
黑板上初始有 共 个整数。
每轮 Alice 先擦除一个数 ,然后 Bob 擦除一个数 ,要求 。
无法行动的玩家输。双方最优,判断谁获胜。
第一步:核心观察
Alice 只有在她的回合开始时没有数字可擦除时才会输。
这意味着如果 是奇数,Alice 至少会在最后一轮先手擦除最后一个数,之后 Bob 无法行动,因此 Alice 必胜。
实际上,更精确地说,Bob 只有在能够将全部数字配成满足条件的对 时才能赢。
第二步:模 4 等价性
条件 只取决于 和 。
因此,我们可以将所有数字按模 的余数分类,余数相同的数字在游戏中视为等价。设 分别表示余数为 的数的个数。
第三步:配对条件
要使 Bob 能每次都回应 Alice 的选择,他必须能对所有数字进行完美配对,使得每对 满足 与 配对为:
- 与 配对(因为 )
- 与 配对(因为 )
因此,Bob 获胜的充要条件是:
否则,Alice 可以选一个无法配对的数(比如多出来的 或 ),使得 Bob 无法行动,Alice 立即获胜。
第四步:计数余数个数
对于 个数 ,它们的余数分布为:
第五步:化简条件
当且仅当 。
当且仅当 。因此, 且 等价于
此时 Bob 获胜;否则 Alice 获胜。
第六步:最终结论
$$\text{winner} = \begin{cases} \text{Bob}, & \text{if } n \equiv 0 \pmod{4}, \\ \text{Alice}, & \text{otherwise}. \end{cases} $$
代码实现
O(n) 版本(按余数计数)
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; vector<int> cnt(4); for (int i = 0; i < n; i++) { cnt[i % 4]++; } cout << (cnt[0] == cnt[3] && cnt[1] == cnt[2] ? "Bob" : "Alice") << '\n'; } int main() { int t; cin >> t; while (t--) solve(); }O(1) 版本(直接判断)
#include <bits/stdc++.h> using namespace std; void solve() { int n; cin >> n; cout << (n % 4 == 0 ? "Bob" : "Alice") << '\n'; } int main() { int t; cin >> t; while (t--) solve(); }
验证样例
输出 2 Alice 4 0 Bob 5 1 Alice 7 3 100 0 Bob 与题目输出一致。
总结
本题的关键在于:
- 将数字按模 等价分类。
- 认识到 Bob 获胜的唯一方式是能完美配对 与 、 与 。
- 推导出该条件等价于 是 的倍数。
- 从而得到简单的 解法。
- 1
信息
- ID
- 6232
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者