07年论文的第一个例题,看了2天都没看懂,那句把每一颗石子看作是一堆石子,如果它是第p堆中的石子,把么它所代表的这堆石子的个数为n-1-p,晚上看电影突然想明白了,意思是如果第p堆一开始为t,那么就可以看做t个数目为n-1-p的石子。一切问题迎刃而解
写了个O(n^3)的算法,但感觉不用枚举,还能有优化
/* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; int n; int sg[25]; int org[25]; void init() { int vis[100],i,j,k;//vis开大点 防溢出 sg[0]=0; for(i=1;i<23;i++) { memset(vis,0,sizeof(vis)); for(j=0;j<i;j++) for(k=j;k<i;k++) { vis[sg[j]^sg[k]]=1; } for(j=0;vis[j];j++); sg[i]=j; } } int main() { int C=0; init(); while(~scanf("%d",&n)&&n) { int t,i,j,k,ans=0; for(i=0;i<n;i++) { scanf("%d",&t); org[i]=t; if(t&1) ans^=sg[n-i-1]; } bool ok=1; printf("Game %d: ",++C); for(i=0;ok&&i<n;i++) if(org[i]) for(j=i+1;ok&&j<n;j++) for(k=j;ok&&k<n;k++) if((ans^sg[n-i-1]^sg[n-j-1]^sg[n-k-1])==0) { printf("%d %d %d\n",i,j,k); ok=0; } if(ok)puts("-1 -1 -1"); } }