标签:
题意:
有n堆石子,alice先取,每次可以选择拿走一堆石子中的1~x(该堆石子总数) ,也可以选择将这堆石子分成任意的两堆。alice与bob轮流取,取走最后一个石子的人胜利。
思路:
因为数的范围比较大,所以最好通过SG打表的结果找出规律在解。
sg(4k+1)=4k+1;sg(4k+2)=4k+2;sg(4k+3)=4k+4; sg(4k)=4k-1;
1 2 4 3 5 6 8 7
Sample Input
2
3
2 2 3
2
3 3
Sample Output
Alice
Bob
SG打表找规律
1 #include<iostream> 2 # include <cstdio> 3 #include<string.h> 4 # include <stdlib.h> 5 #define N 1000001 6 using namespace std; 7 int sg[N]; 8 int g(int x) 9 { 10 int mex[1000]; 11 memset(mex,0,sizeof(mex)); 12 if(sg[x]!=-1) return sg[x]; 13 for(int i=x-1;i>=0;i--) 14 { 15 mex[g(i)]=1; 16 } 17 for(int i=1;i<=x/2;i++) 18 { 19 int ans=0; 20 ans^=g(i); 21 ans^=g(x-i); 22 mex[ans]=1; 23 } 24 for(int i=0;;i++) 25 if(!mex[i]) return sg[x]=i; 26 } 27 int main() 28 { 29 int t , n ,x ; 30 scanf("%d",&t); 31 memset(sg,-1,sizeof(sg)); 32 sg[0]=0; 33 while(t--) 34 { 35 scanf("%d",&n); 36 for(int i=0;i<n;i++) 37 { 38 scanf("%d",&x); 39 g(x); cout<<"sg[x]= "<<sg[x]<<endl; 40 } 41 for(int i=0;i<=100;i++) 42 { 43 cout<<sg[i]<<" "; 44 if(i%10==0) system("pause"); 45 }cout<<endl; 46 } 47 return 0; 48 }
题解代码
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 using namespace std ; 5 6 7 int main () 8 { 9 int T ; 10 scanf("%d" , &T) ; 11 while(T--) 12 { 13 int n ; 14 scanf("%d" , &n) ; 15 int x ; 16 int sum = 0 ; 17 while(n--) 18 { 19 scanf("%d" , &x) ; 20 if (x % 4 == 1) 21 sum ^= x ; 22 else if (x % 4 == 2) 23 sum ^= x ; 24 else if (x % 4 == 3) 25 sum ^= (x+1) ; 26 else 27 sum ^= (x-1) ; 28 } 29 if (sum == 0) 30 printf("Bob\n") ; 31 else 32 printf("Alice\n") ; 33 } 34 35 36 return 0 ; 37 }
标签:
原文地址:http://www.cnblogs.com/-Buff-/p/4490775.html