给出n堆石子, 每次可以取一堆中的任意x个(x>=1), 或者将一堆石子拆成两堆, 取到最后一堆的胜。
这个题需要打sg表找规律, 打表程序看代码。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 int sg[10000]; 20 int mex(int x) { 21 if(~sg[x]) 22 return sg[x]; 23 int vis[100]; 24 mem(vis); 25 for(int i = 0; i<x; i++) { 26 sg[i] = mex(i); 27 vis[sg[i]] = 1; 28 } 29 for(int i = 1; i<=x/2; i++) { 30 int ans = 0; 31 ans ^= sg[i]; 32 ans ^= sg[x-i]; 33 vis[ans] = 1; 34 } 35 for(int i = 0; ; i++) 36 if(!vis[i]) 37 return i; 38 } 39 int main() 40 { 41 int t, n, x; 42 cin>>t; 43 while(t--) { 44 scanf("%d", &n); 45 int ans = 0; 46 while(n--) { 47 scanf("%d", &x); 48 if(x%4==0) 49 x--; 50 else if(x%4==3) 51 x++; 52 ans ^= x; 53 } 54 if(ans) 55 cout<<"Alice"<<endl; 56 else 57 cout<<"Bob"<<endl; 58 } 59 return 0; 60 }