[HNOI2007]分裂游戏

Posted by Dispwnl on April 21, 2019

题目

题解

最后情况肯定是所有豆子都在最后一个瓶子里

如果有个瓶子里有偶数个豆子不影响最后的胜负,因为无论先手走什么后手都可以模仿先手

所以可以把每个瓶子看成一个独立的游戏,处理出来$n$个瓶子时$SG$的值

至于找方案,可以$O(n^3)$枚举$i,j,k$,判断去掉$SG_i$异或上$SG_j,SG_k$(即规定了第一步应该这么走)是否满足必胜即可

代码

# include<iostream>
# include<cstring>
# include<cstdio>
# include<algorithm>
using namespace std;
const int MAX=101;
int T,n;
int a[MAX],sg[MAX];
bool use[MAX];
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		memset(sg,-1,sizeof(sg));
		sg[n]=0;
		for(int i=1;i<=n;++i)
		  scanf("%d",&a[i]),a[i]%=2;
		for(int i=n-1;i>=1;--i)
		  {
		  	memset(use,0,sizeof(use));
		  	for(int j=i+1;j<=n;++j)
		  	  for(int k=j;k<=n;++k)
		  	    use[sg[j]^sg[k]]=1;
		  	for(int j=0;!~sg[i];++j)
		  	  if(!use[j]) sg[i]=j;
		  }
		int sum=0,ans=0,I=0,J=0,K=0;
		for(int i=1;i<=n;++i)
		  if(a[i]) sum^=sg[i];
		for(int i=1;i<n;++i)
		  if(a[i]) for(int j=i+1;j<=n;++j)
		    for(int k=j;k<=n;++k)
		      if(!(sum^sg[i]^sg[j]^sg[k]))
		      {
		      	if(!I) I=i,J=j,K=k;
		      	++ans;
			  }
		printf("%d %d %d\n%d\n",I-1,J-1,K-1,ans);
	}
	return 0;
}