题意:与原来基本的尼姆博弈不同的是,可以将一堆石子分成两堆石子也算一步操作,其它的都是一样的。
分析:由于石子的堆数和每一堆石子的数量都很大,所以肯定不能用搜索去求sg函数,现在我们只能通过找规律的办法求得sg的规律。
通过打表找规律可以得到如下规律:if(x%4==0) sg[x]=x-1; if(x%4==1||x%4==2) sg[x]=x; if(x%4==3)
sg[x] = x+1。
打表代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;int sg[1000];
int calsg(int x)
{
int next[105],i,flag;
memset(next,0,sizeof(next));for(i=1;i<=x/2;i++)
{
flag=sg[i]^sg[x-i];
// printf("%d %d\n",sg[i],sg[x-i]);
next[flag]=1;
}for(i=1;i<=x;i++)
{
if(sg[x-i]==-1)
sg[x-i]=calsg(x-i);
next[sg[x-i]]=1;
}for(i=0; ;i++)
if(next[i]==0)
return i;
}int main()
{
int i;
memset(sg,-1,sizeof(sg));
sg[0]=0;sg[1]=1;
//sg[2]=2;
printf("0\n1\n");
for(i=2;i<=100;i++)
{
sg[i]=calsg(i);
printf("%d\n",sg[i]);
}return 0;
}
ac代码:
#include<stdio.h>
#include<string.h>
#include<math.h>int n;
int main()
{
int T,i,res,x;
scanf("%d",&T);
while(T--)
{
res=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&x);
if(x%4==0)
res=res^(x-1);
else if(x%4==1||x%4==2)
res=res^(x);
else
res=res^(x+1);
}
if(res!=0)
printf("Alice\n");
else
printf("Bob\n");
}
return 0;
}
hdu 3032(博弈sg函数),布布扣,bubuko.com