Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1710 Accepted Submission(s): 845
2 3 2 2 3 2 3 3
Alice Bob
题意:nim博弈的变形,n堆石头,每次可以在一堆中取任意数目的石头,或者把它分成两堆不为0的堆;最后取完的获胜。
分析:一步一步的推SG值...
很明显sg[0]=0, sg[1]=1;
然后状态2的后继有:0,1和(1, 1), 他们的sg值为0,1,0;所以sg[2]=2;
然后状态3的后继有:0,1,2和(1, 2), 他们的sg值为0,1,2,3;所以sg[3]=4;
然后状态4的后继有:0,1,2,3、(1, 3)和(2, 2), 他们的sg值为0,1,2,4,5,0;所以sg[4]=3;
..........
最后根据所推出的sg值,得到:对于所有的k >= 0,有 sg( 4k+1 ) = 4k+1; sg( 4k+2 ) = 4k+2; sg( 4k+3 )= 4k+4; sg( 4k+4 ) = 4k+3。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int INF = 1e9;
const int MOD = 1e9+7;
#define ll long long
#define CL(a,b) memset(a,b,sizeof(a))
#define lson (i<<1)
#define rson ((i<<1)|1)
#define N 1000010
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int main()
{
int T,n,x;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int ans = 0;
for(int i=1; i<=n; i++)
{
scanf("%d",&x);
if(x%4==0) ans ^= (x-1);
else if(x%4==1||x%4==2) ans ^= x;
else ans ^= (x+1);
}
if(ans) cout<<"Alice"<<endl;
else cout<<"Bob"<<endl;
}
return 0;
}
原文:http://blog.csdn.net/d_x_d/article/details/52124418