【博弈论】【SG函数】【枚举】bzoj1188 [HNOI2007]分裂游戏
2015-03-14 10:39
330 查看
因为第i个瓶子里的所有豆子都是等价的,设sg(i)表示第i个瓶子的sg值,可以转移到sg(j)^sg(k)(i<j<n,j<=k<n)的状态。
只需要考虑豆子数是奇数的瓶子啦,因为如果豆子数是偶数,重复异或是没有意义的。
对于方案数什么的……枚举就好了。
只需要考虑豆子数是奇数的瓶子啦,因为如果豆子数是偶数,重复异或是没有意义的。
对于方案数什么的……枚举就好了。
#include<cstdio> #include<cstring> #include<set> using namespace std; int T,n,a[21],SG[21]; int sg(int x) { if(SG[x]!=-1) return SG[x]; set<int>S; for(int i=x+1;i<n;++i) for(int j=i;j<n;++j) S.insert(sg(i)^sg(j)); for(int i=0;;++i) if(S.find(i)==S.end()) return SG[x]=i; } int main() { scanf("%d",&T); for(;T;--T) { memset(SG,-1,sizeof(SG)); int ans=0,sum=0; scanf("%d",&n); for(int i=0;i<n;++i) { scanf("%d",&a[i]); if(a[i]&1) ans^=sg(i); } if(ans) { for(int i=0;i<n;++i) if(a[i]) for(int j=i+1;j<n;++j) for(int k=j;k<n;++k) { --a[i]; ++a[j]; ++a[k]; int t=0; for(int l=0;l<n;++l) if(a[l]&1) t^=sg(l); if(!t) { ++sum; if(sum==1) printf("%d %d %d\n",i,j,k); } ++a[i]; --a[j]; --a[k]; } printf("%d\n",sum); } else printf("-1 -1 -1\n0\n"); } return 0; }
相关文章推荐
- [BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】
- BZOJ 1188: [HNOI2007]分裂游戏 博弈论
- bzoj 1188: [HNOI2007]分裂游戏 sg函数
- [SG函数] BZOJ1188: [HNOI2007]分裂游戏
- [BZOJ1188][HNOI2007]分裂游戏(博弈论)
- 【SG函数】BZOJ1188(HNOI2007)[分裂游戏]题解
- bzoj 1188 [HNOI2007]分裂游戏(SG函数,博弈)
- [BZOJ1188][HNOI2007]分裂游戏(SG函数)
- bzoj 1188: [HNOI2007]分裂游戏(sg函数)
- [BZOJ1188][HNOI2007]分裂游戏(博弈SG函数)
- BZOJ1188 [HNOI2007]分裂游戏(SG函数)
- BZOJ 1188 [HNOI2007]分裂游戏 SG函数
- bzoj 1188 : [HNOI2007]分裂游戏 sg函数
- BZOJ1188 [HNOI2007]分裂游戏(SG函数)
- bzoj1188 [HNOI2007]分裂游戏
- BZOJ1188: [HNOI2007]分裂游戏(洛谷P3185)
- BZOJ 1188 [HNOI 2007]分裂游戏 (博弈)
- bzoj1188: [HNOI2007]分裂游戏
- bzoj1188: [HNOI2007]分裂游戏
- BZOJ1188 [HNOI2007]分裂游戏