[BZOJ 1874] [BeiJing2009 WinterCamp] 取石子游戲
阿新 • • 發佈:2018-11-23
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; }