题目描述:
(<--这个)
组合游戏,——把每个石头看做一个游戏,
Multi_game——消去i上的石子后,,k上的游戏又多了一个;
于是就套用multi_game的模型即可
求解SG函数时,发现一个游戏的后继是谁只与其位置有关,于是可以用一个SG值代替一堆游戏的SG值;
求解完所有SG值,后异或即可;
代码:
#include<cstdio>
#include<cstring>
using namespace std;
int a[],n,sg[],g[];
int SG(int );
int main()
{
int i,j,k,T,ans,tot;
scanf("%d",&T);
while(T--){
ans=;tot=;
memset(sg,-,sizeof(sg));
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
for(i=;i<=n;i++)
if(a[i]&)
ans^=SG(i);
if(ans==)
printf("-1 -1 -1\n0\n");
else{
for(i=;i<=n;i++)
for(j=i+;j<=n;j++)
for(k=j;k<=n;k++)
if((ans^SG(i)^SG(j)^SG(k))==){
if(!tot)printf("%d %d %d\n",i-,j-,k-);
tot++;
}
if(!tot)printf("-1 -1 -1\n");
printf("%d\n",tot);
}
}
return ;
}
int SG(int x){
int i,j;
if(sg[x]!=-)return sg[x];
if(x==n)return sg[x]=;
memset(g,,sizeof(g));
for(i=x+;i<=n;i++)
for(j=i;j<=n;j++)
g[SG(i)^SG(j)]=;
for(i=;;i++)
if(!g[i])return sg[x]=i;
}