1. 程式人生 > >bzoj1188: [HNOI2007]分裂遊戲

bzoj1188: [HNOI2007]分裂遊戲

這是一道很有特點的博弈啊。。。

首先我們可以把每個不同的豆子看成一個子遊戲,然後它的SG值就是它所處於的位置,知道這一點就簡單了

然後對於當前勝負判斷就容易弄了,只要那些豆子數%2==1的SG值合起來就好

方案數可以暴力列舉

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int n,p[30
],sg[30]; bool v[11000]; int SG(int i) { if(sg[i]!=-1)return sg[i]; memset(v,false,sizeof(v)); for(int j=i+1;j<=n;j++) for(int k=j;k<=n;k++) v[SG(j)^SG(k)]=true; for(int u=0;;u++) if(v[u]==false) {sg[i]=u;return sg[i];} } int main() {
int T; scanf("%d",&T); while(T--) { int ans=0; scanf("%d",&n); memset(sg,-1,sizeof(sg));sg[n]=0; for(int i=1;i<=n;i++) { scanf("%d",&p[i]); if(p[i]%2==1)ans^=SG(i); } int sum=0;
for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) for(int k=j;k<=n;k++) if((ans^SG(i)^SG(j)^SG(k))==0) { sum++; if(sum==1) printf("%d %d %d\n",i-1,j-1,k-1); } if(sum==0)printf("-1 -1 -1\n"); printf("%d\n",sum); } return 0; }