LightOJ 1199 Partitioning Game(sg函数)题解
题意:可以把一堆石子分成不相等的两堆,不能操作为败
思路:把一个石子拆成两个,变成了两个独立的游戏,mex里加上两者的sg异或。sg打表。
代码:
#include<set> #include<map> #include<stack> #include<cmath> #include<queue> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> typedef long long ll; const int maxn = 1e4 + 10; const int seed = 131; const ll MOD = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; int sg[maxn], s[maxn]; int main(){ sg[0] = 0; for(int i = 1; i < maxn; i++){ memset(s, 0, sizeof(s)); for(int j = 1; j * 2 < i; j++){ s[sg[j] ^ sg[i - j]] = 1; } for(int j = 0; j < maxn; j++){ if(!s[j]){ sg[i] = j; //cout << j << endl; break; } } } int T, Case = 1; scanf("%d", &T); while(T--){ int n; scanf("%d", &n); ll ans = 0; while(n--){ ll a; scanf("%lld", &a); ans ^= sg[a]; } if(ans) printf("Case %d: Alice\n", Case++); else printf("Case %d: Bob\n", Case++); } return 0; }