有n堆石子,alice先取,每次可以选择拿走一堆石子中的1~x(该堆石子总数) ,也可以选择将这堆石子分成任意的两堆。alice与bob轮流取,取走最后一个石子的人胜利。
打表代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 const int N=1000010; 7 int sg[N]; 8 //注意 S数组要按从小到大排序 SG函数要初始化为-1 对于每个集合只需初始化1遍 9 //n是集合s的大小 S[i]是定义的特殊取法规则的数组 10 int s[110]; 11 int SG_dfs(int x) 12 { 13 int i; 14 if(sg[x]!=-1) 15 return sg[x]; 16 bool vis[110]; 17 memset(vis,0,sizeof(vis)); 18 for(int i=x-1;i>=0;i--) //第一种取法 19 vis[SG_dfs(i)]=1; 20 for(i=1;i<=x/2;i++) //分开取法 21 { 22 int ans=0; 23 ans^=SG_dfs(i); 24 ans^=SG_dfs(x-i); 25 vis[ans]=1; 26 } 27 int e; 28 for(i=0;;i++) 29 if(!vis[i]) 30 { 31 e=i; 32 break; 33 } 34 return sg[x]=e; 35 } 36 int main() 37 { 38 int t,n; 39 scanf("%d",&t); 40 memset(sg,-1,sizeof(sg)); 41 while(t--) 42 { 43 scanf("%d",&n); 44 int x; 45 for(int i=0;i<n;i++) 46 { 47 scanf("%d",&x); 48 SG_dfs(x); 49 printf("sg[%d]=%d\n",x,sg[x]); 50 } 51 for(int i=0;i<=100;i++){ 52 printf("%d: %d\n",i,sg[i]); 53 //if(i%10==0) 54 //system("pause"); 55 } 56 printf("\n"); 57 } 58 return 0; 59 }
之后异或一下即可,2333
时间: 2024-10-14 05:33:01