「解题报告」石子游戏
题目大意
Alice 和 Bob 在
堆石子中取石子, 这 堆石子的数量分别是 , Alice 先取, 每人只能取 个, 假如双方都使用最优策略, 求当 为 中的每个数字时谁必胜。
样例输入
4 1 2 3 4
样例输出
Bob Alice Bob Alice
题解
本题需要分两部分来解答。
首先,当
我们可以想办法来构造一个 Nim 游戏, 这样就可以知道谁必胜。
Nim 游戏的要求是每人可以取任意数量的石子, 而本题是固定数量, 所以需要进行一定的调整。
我们可以将每一堆分为若干个
举个例子, 有两堆
那么我们就将问题转换为了, 对于
我们可以对每一位进行运算,再统计每一位是
设
现在的问题是如何在
考虑第
000
001
010
011
100
101
110
111
不难发现,对于第
所以我们可以定义以下数组:
注意这个定义很关键,一定要仔细体会。
我们可以得出以下式子:
这个式子什么意思呢?
我们可以画个图:
| 0 | 1 | 0 | 1 | 0 | 1 |
|2^(j+1)| | | | | ···
|2^j|2^j| | | | |
↑ ↑
f(i, j) f(i + 2^(j+1), j)
也就是将当前
那么我们如何计算
我们接着画个图:
ky (k+1)y
↓ ↓
| 0 | 1 | 0 | 1 | 0 | 1 | | 0 |1|1| 0 |
|2^(j+1)| | | | | ··· | | | | |
|2^j|2^j| | | | | | | | | |
↑ ↑ ↑ ↑
f(ky, j) f(ky + 2^(j+1), j) ① ②
先看这种情况:我们只需要将
每一段
注意边界可能会有一些加 1 减 1, 自己推一下就可以了。
代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2000005;
int n, a, c[MAXN], w[MAXN];
int f[MAXN][20];
int main() {
#ifdef DEBUG
freopen("T1.in", "r", stdin);
freopen("T1.out", "w", stdout);
#else
freopen("stone.in", "r", stdin);
freopen("stone.out", "w", stdout);
#endif
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &c[i]), w[c[i]]++;
for (int i = 1; i <= n; i++) c[i] = c[i - 1] + w[i];
for (int i = n + 1; i <= 3 * n; i++) c[i] = c[n];
for (int i = n; i >= 0; i--) {
for (int j = 0; (1 << j) <= n; j++) {
f[i][j] = f[i + (1 << (j + 1))][j] + c[i + (1 << (j + 1)) - 1] - c[i + (1 << j) - 1];
}
}
for (int x = 1; x <= n; x++) {
int y = x + 1;
for (int j = 0; (1 << j) <= n; j++) {
int cnt = 0;
for (int k = 0; k <= ceil(n / (double) y); k++) {
int q = f[k*y][j] - f[(k+1)*y-(y%(1<<(j+1)))][j] + ((y%(1<<(j+1)) >(1<<j)) ? (c[(k+1)*y - 1] - c[(k+1)*y-y%(1<<(j+1))+(1<<j)-1]) : 0);
cnt += q;
//printf("[%d,%d):%d\n", k*y, (k+1)*y, q);
}
//printf("digit %d: %d\n", j, cnt);
if (cnt % 2 != 0) {
printf("Alice ");
goto next;
}
}
printf("Bob ");
next:
continue;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】