一。巴什博弈
只是最简单的博弈了,只简单说一下满足条件,一堆总数为n个,每次可以取1-m个石头。 核心是n=(m+1)*r+s;也就是说用n%(m+1) 判断是否等于0即可。
例题:hdu 1846
巴什博弈
int main()
{
int n;
cin>>n;
while(n--)
{
int a,b;
cin>>a>>b;
int t=a%(b+1);
if(t>=1)
{
cout<<"first"<
要求是在一堆里,轮流取石头,每次取的石头要求在1-上一次对手取的石头的2倍之间 包括两个端点,核心是把这个数分解成斐波拉契数列,换句话说,判断这个n是否是斐波拉契数即可。
例题:hdu2516
斐波那契博弈
int main()
{
int n;
int a[maxn];
a[0]=2;
a[1]=3;
for(int i=2;i<=50;i++)
{
a[i]=a[i-1]+a[i-2];
}
while(cin>>n,n)
{
int flag=0;
for(int i=0;i<=50;i++)
{
if(n==a[i])
{
puts("Second win");
flag=1;
break;
}
}
if(!flag)
{
puts("First win");
}
}
}
三。威佐夫博弈。
要求是两堆石头,两个人轮流从某一堆同时从两堆中取同样多的物品。最少一个,多则无限。
这个博弈的关键在于一个黄金分割数。
就要提到一种叫奇异局势。
意思是B-A(当然保证B>A) A=黄金分割数*(B-A)的话就是奇异局势。核心就在这里。
例题:poj 1067
威佐夫博弈
int main()
{
int a,b;
while(cin>>a>>b)
{
if(a>b)
swap(a,b);
int c=floor((b-a)*((sqrt(5.0)+1)/2));
if(c==a)
{
puts("0");
}
else
{
puts("1");
}
}
}
四。尼姆博弈。要求是n堆里面,取一堆任意多的物品。每次取一个,多者不限。
核心也就是异或。
例题:hdu 1850
尼姆博弈
int main()
{
int m;
while(cin>>m,m)
{
int ans=0,sum=0;
int a[maxx];
for(int i=1;i<=m;i++)
{
cin>>a[i];
ans^=a[i];
}
if(ans==0) puts("0");
else
{
for(int i=1;i<=m;i++)
{
int k=ans^a[i];
if(k
五。SG值。
例题:hdu 1847
SG值
#include
//#include
//#include
//using namespace __gnu_pbds;
using namespace std;
#define pi acos(-1)
#define endl '\n'
#define me(x) memset(x,0,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,-1,-1,1,1};
const int dy[]={0,1,0,-1,1,-1,1,-1};
const int maxn=1e3+5;
const int maxx=2e5+100;
const double EPS=1e-7;
const int mod=1000000007;
templateinline T min(T a,T b,T c) { return min(min(a,b),c);}
templateinline T max(T a,T b,T c) { return max(max(a,b),c);}
templateinline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
templateinline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
//typedef tree,rb_tree_tag,tree_order_statistics_node_update> rbtree;
/*lch[root] = build(L1,p-1,L2+1,L2+cnt);
rch[root] = build(p+1,R1,L2+cnt+1,R2);中前*/
/*lch[root] = build(L1,p-1,L2,L2+cnt-1);
rch[root] = build(p+1,R1,L2+cnt,R2-1);中后*/
long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}
int sg[maxx];
int a[100];
int mex(int x)
{
if(sg[x]!=-1) return sg[x];
int vis[maxn];
me(vis);
for(int i=0;i<=10;i++)
{
int temp=x-a[i];
if(temp<0) break;
sg[temp]=mex(temp);
vis[sg[temp]]=1;
}
for(int i=0;;i++)
{
if(!vis[i])
{
sg[x]=i;
break;
}
}
return sg[x];
}
int main()
{
int n;
a[0]=1;
for(int i=1;i<=10;i++)
{
a[i]=a[i-1]*2;
}
while(cin>>n)
{
memset(sg,-1,sizeof(sg));
if(mex(n)) puts("Kiki");
else
puts("Cici");
}
}