原题链接
分析
一堆可以变成两堆,对于每堆的一种子情况来说都有:
$$
sg(a,b)\rightarrow sg(a)\ xor\ sg(b)
$$
只需要遍历a,b的所有情况就可以了。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include <bits/stdc++.h> using namespace std; const int N = 101; int n; int f[N];
int sg(int x) { if(f[x] != -1) return f[x]; unordered_set<int> S; for(int k = x - 1; k >= 0; --k) { for(int j = x - 1; j >= 0; --j) { S.insert(sg(k) ^ sg(j)); } } for(int i = 0; ; ++i) if(S.count(i) == 0) { return f[x] = i; } }
int main() { scanf("%d", &n); memset(f, -1, sizeof f); f[0] = 0; int res = 0; for(int i = 0; i < n; ++i) { int a; scanf("%d", &a); res ^= sg(a); } if(res) printf("Yes"); else printf("No"); return 0; }
|