hdu5795 A Simple Nim(Multi-SG打表)

题目

n堆石子,每次可以选一堆石子取若干(像Nim游戏一样)

也可以把一堆石子分成三堆非空石子,

取走最后一颗石子的胜,给定局面问谁必胜

思路来源

https://blog.csdn.net/Code92007/article/details/87892307

题解

Multi-SG打表,考虑三个子状态为后继即可

先把100以内表打出来,

hdu5795 A Simple Nim(Multi-SG打表)_第1张图片

发现除以8余7的正整数和整除8的正整数的sg值互换了

其余就是本身,这就是规律

代码1(打表找SG规律)

#include
#include
#include
#include 
using namespace std;
const int maxn=1e3+5;
int T,n,sg[105];
bool vis[105];
void getsg()
{
	sg[0]=0;sg[1]=1;
	for(int i=2;i<=100;++i)
	{
		memset(vis,0,sizeof(vis));
		for(int j=0;j<=i-1;++j)
		{
			vis[sg[j]]=1;
		}
		for(int k=1;k<=i;++k)
		{
			for(int l=1;l<=i;++l)
			{
				if(k+l>i)break;
				for(int m=1;m<=i;++m)
				{
					if(k+l+m>i)break;
					if(k+l+m==i)vis[sg[k]^sg[l]^sg[m]]=1; 
				}
			}
		}
		for(int v=0;;++v)
		{
		 if(!vis[v])
		 {
		 sg[i]=v;
		 break;
	     }
	    }
	}
	for(int i=0;i<=100;++i)
	{
		printf("sg[%3d]:%3d ",i,sg[i]);
	    if((i+1)%10==0)puts("");	
	}
}
int main()
{
	getsg();
	return 0; 
} 

代码2(输出)

#include
#include
#include
#include 
using namespace std;
int getsg(int x)
{
	if(x&&x%8==0)return x-1;
	if((x+1)%8==0)return x+1;
	return x;
}
int t;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		int n,ans=0;
		scanf("%d",&n);
		for(int i=0;i

 

你可能感兴趣的:(博弈)