bzoj 1188: [HNOI2007]*游戏

 1  
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<cstring>
 5 using namespace std;
 6 bool ma[10009];
 7 int n,T,f[30],a[30];
 8 int work(int a1)
 9 {
10     if(f[a1]!=-1)
11       return f[a1];
12     memset(ma,0,sizeof(ma));
13     for(int i=a1+1;i<=n;i++)
14       for(int j=i;j<=n;j++)
15         ma[work(i)^work(j)]=1;
16     for(int i=0;;i++)
17       if(!ma[i])
18         {
19             f[a1]=i;
20             return i;
21         }
22 }
23 int main()
24 {
25     scanf("%d",&T);
26     for(;T;T--)
27       {
28         int tot,ans;
29         tot=ans=0;
30         scanf("%d",&n);
31         memset(f,-1,sizeof(f));
32         f[n]=0;
33         for(int i=1;i<=n;i++)
34           scanf("%d",&a[i]);
35         for(int i=1;i<=n;i++)
36           if(a[i]&1)
37             ans^=work(i);
38         for(int i=1;i<n;i++)
39           for(int j=i+1;j<=n;j++)
40             for(int k=j;k<=n;k++)
41               {
42                 if((ans^work(i)^work(j)^work(k))!=0)
43                   continue;
44                 if(!tot)
45                   printf("%d %d %d
",i-1,j-1,k-1);
46                 tot++;
47               }
48         if(!tot)
49           printf("-1 -1 -1
");
50         printf("%d
",tot);
51       }
52     return 0;
53 }

博弈游戏,先求出所有节点的sg值,再枚举每一种拿的可能性,改变总sg值,如果总改变后sg值为0,那就是一种方案。

原文地址:https://www.cnblogs.com/xydddd/p/5236871.html