[BZOJ1188/Luogu3185][HNOI2007]分裂游戏

题目链接:

BZOJ1188

Luogu3185

博弈论。

首先,每一堆石子都是互相独立,不影响的,那么就只需求解每一堆的\(SG\)函数\(Xor\)即可。

再想,对于每一堆石子,里面的每一个石头都是互相独立的,那么就只需求解一个石子的\(SG\)函数,再用\(p_i\)\(Xor\)起来就得到了答案。

那么如果是奇数不变,偶数个则为\(0\)

对于一个石子的\(SG\)函数暴力求即可。

妙啊喵啊

时间复杂度 \(O(Tn^3)\)

#include <cstdio>
#include <cstring>

int t,n,p[25],SG[25];
bool Bus[505];

int main()
{
	for(scanf("%d",&t);t--;)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;++i)scanf("%d",&p[i]);//这里用1~n编号
		for(int i=n;i>=1;--i)
		{
			memset(Bus,0,sizeof Bus);
			for(int j=i+1;j<=n;++j)
				for(int k=j;k<=n;++k)
					Bus[SG[j]^SG[k]]=true;//后继状态mex
			for(int j=0;j<=500;++j)
				if(!Bus[j])
					SG[i]=j,j=500;
		}
		int TSG=0,p1=0,p2=0,p3=0,Cnt=0;
		for(int i=1;i<=n;++i)
			if(p[i]&1)
				TSG^=SG[i];//是奇数,只需xor一次
		if(TSG)
			for(int i=1;i<n;++i)
				for(int j=i+1;j<=n;++j)
					for(int k=j;k<=n;++k)
						if(!(TSG^SG[i]^SG[j]^SG[k]))//能使Xor和变为0(必败)
						{
							++Cnt;
							if(!p1)p1=i,p2=j,p3=k;
						}
		printf("%d %d %d\n%d\n",p1-1,p2-1,p3-1,Cnt);
	}
	return 0;
}
posted @ 2018-12-31 19:04  LanrTabe  阅读(209)  评论(0编辑  收藏  举报