UVA 1378 A Funny Stone Game (经典博弈)
2017-03-03 19:44
483 查看
题目传送门
代码不是关键,关键的是对博弈和sg函数的理解。重点是在构造sg函数的时候是将一个石头看成一个堆,所以按照sg函数的定义后继状态为两个石头构成的堆。然后根据对称性原理和xor的性质,在某个堆,只有石头个数为奇数时才会对参与xor,才会对最后答案有贡献。
最后枚举第一步操作的可能性使得xor为0即转入必败态。此时相当于去掉第i个堆里的一个石头,在第j堆和第k堆加上个一块石头。
代码不是关键,关键的是对博弈和sg函数的理解。重点是在构造sg函数的时候是将一个石头看成一个堆,所以按照sg函数的定义后继状态为两个石头构成的堆。然后根据对称性原理和xor的性质,在某个堆,只有石头个数为奇数时才会对参与xor,才会对最后答案有贡献。
最后枚举第一步操作的可能性使得xor为0即转入必败态。此时相当于去掉第i个堆里的一个石头,在第j堆和第k堆加上个一块石头。
#include <bits/stdc++.h> using namespace std; const int N=100005; int vis[80],sg[30],num[30]; int init() { sg[1]=0; for(int i=2;i<=23;i++) { memset(vis,0,sizeof(vis)); for(int j=1;j<i;j++) { for(int k=1;k<=j;k++) { vis[sg[j]^sg[k]]=1; } } for(int q=0;q<80;q++) { if(!vis[q]) { sg[i]=q; break; } } } return 0; } int main() { int n,t=0; init(); while(scanf("%d",&n)!=EOF) { int ans=0; if(!n) break; for(int i=1;i<=n;i++) { scanf("%d",&num[i]); if(num[i]&1) { ans^=sg[n+1-i]; } } cout<<ans<<endl; printf("Game %d: ",++t); if(!ans) { printf("-1 -1 -1\n"); continue; } int flag=1; for(int i=1;i<=n&&flag;i++) { if(num[i]) for(int j=i+1;j<=n&&flag;j++) { for(int k=j;k<=n&&flag;k++) { if((ans^sg[n+1-i]^sg[n+1-j]^sg[n+1-k])==0) { printf("%d %d %d\n",i-1,j-1,k-1); flag=0; } } } } } return 0; }
相关文章推荐
- 【UVA1378】A Funny Stone Game (博弈-求SG值-输出方案)
- uva 1378 A Funny Stone Game (博弈-SG)
- UVA 1378 - A Funny Stone Game(博弈)
- uva 1378 A Funny Stone Game 博弈/组合游戏 sg定理
- uva 1378 - A Funny Stone Game(组合游戏)
- uva 1378 A Funny Stone Game(博弈论)
- UVa 1378 A Funny Stone Game [博弈论 SG函数]
- UVA - 1378 A Funny Stone Game (SG定理)
- UVALive 3668 A Funny Stone Game(博弈)
- sg函数_______A Funny Stone Game(uva 1378)
- [UVA1378] A Funny Stone Game && SG函数
- [nim博弈扩展 sg函数] UVALive 3668 A Funny Stone Game
- Uva 1378 - A Funny Stone Game
- uva 1378 - A Funny Stone Game(组合游戏)
- [博弈]A Funny Stone Game
- LA 3668 A Funny Stone Game(博弈,SG定理)
- UVALive 3668 A Funny Stone Game
- UVa 10891 Game of Sum(经典博弈区间DP)
- 杭电1279 Stone Game(经典博弈)
- UVa 11489 - Integer Game (简单博弈 脑筋急转弯)