标签:
BZOJ1188: [HNOI2007]分裂游戏
首先我们可以认为每一个石子都是一个独立的游戏(因为石子之间互不影响),那么我们用sg[i]表示处在i位置的一个石子的sg函数值,那么我们就可以枚举它的后继状态从而计算它的sg函数值。
最后累加ans即可。
1 int v[100],sg[100],a[100]; 2 int main() 3 { 4 freopen("input.txt","r",stdin); 5 freopen("output.txt","w",stdout); 6 int T=read(); 7 while(T--) 8 { 9 int n=read(); 10 sg[n-1]=0; 11 for3(i,n-2,0) 12 { 13 memset(v,0,sizeof(v)); 14 for2(j,i+1,n-1)for2(k,j,n-1)v[sg[j]^sg[k]]=1; 15 for(sg[i]=0;v[sg[i]];sg[i]++); 16 } 17 int ans=0; 18 for0(i,n-1) 19 { 20 a[i]=read(); 21 if(a[i]&1)ans^=sg[i]; 22 } 23 if(!ans)printf("%d %d %d\n%d\n",-1,-1,-1,0); 24 else 25 { 26 int tot=0; 27 for0(i,n-1) 28 for2(j,i+1,n-1) 29 for2(k,j,n-1) 30 if((ans^sg[i]^sg[j]^sg[k])==0) 31 { 32 if(!tot)printf("%d %d %d\n",i,j,k); 33 tot++; 34 } 35 printf("%d\n",tot); 36 } 37 } 38 return 0; 39 }
BZOJ1022: [SHOI2008]小约翰的游戏John
取完最后一个石子者败。先手必胜当且仅当:
1)存在某个a[i]>1,异或和!=0
2)不存在某个a[i]>1,异或和==0
脑补一下证明。不妨把状态补全
3)存在某个a[i]>1,异或和==0
4)不存在某个a[i]>1,异或和!=0
首先2)是必胜,4)是必败
考虑1)的状态,如果>1的a[i]只有一堆,我们就可把他变成4)让对手必败。
否则我们必定可以变成3)
而对于3)情况来说,一定存在至少两个a[i]>1,而每次只能对一堆石子进行操作,操作完了之后的状态一定是1)
我是在这里看的:链接君
(好像出现了循环论证?QAQ)
1 int main() 2 { 3 freopen("input.txt","r",stdin); 4 freopen("output.txt","w",stdout); 5 int T=read(); 6 while(T--) 7 { 8 int n=read(),ans=0,flag=0; 9 for1(i,n){int x=read();if(x>1)flag=1;ans^=x;} 10 if((ans&&flag)||(!ans&&!flag))printf("%s\n","John");else printf("%s\n","Brother"); 11 } 12 return 0; 13 }
标签:
原文地址:http://www.cnblogs.com/zyfzyf/p/4422994.html