Description
每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏。请你求出是否有先手必胜策略,如果有,第一步如何取石子。
Solution
当各堆的 \(SG\) 函数的异或和不为 \(0\) 时为必胜态,证明如下
Code
#include <cstdio>
int n, m, ans, a[15], b[15], sg[1005], f[15];
void getsg() {
for (int i = 1; i <= 1000; ++i) {
for (int j = 1; j <= m; ++j)
if (i - b[j] >= 0) f[sg[i-b[j]]] = i;
for (int j = 0; j <= 10; ++j)
if (f[j] != i) { sg[i] = j; break; }
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
scanf("%d", &m);
for (int i = 1; i <= m; ++i) scanf("%d", &b[i]);
getsg();
for (int i = 1; i <= n; ++i) ans ^= sg[a[i]];
if (!ans) puts("NO");
else {
puts("YES");
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
if ((ans ^ sg[a[i]] ^ sg[a[i]-b[j]]) == 0) {
printf("%d %d\n", i, b[j]); return 0;
}
}
return 0;
}