威佐夫博弈
有两堆各若干的物品,两人轮流从其中一堆中取至少一件物品,最多不限,或从两堆中同时取相同件物品,规定最后取光者胜利
若两堆物品的初始值为(x,y)(x<y) 令z=y-x,w=(int)[(sqrt(5)+1)/2*z](黄金分割率) 若w=x 则先手必败 否则先手必胜
if(x>y)
swap(x,y);
z=y-x;
w=(sqrt(5)+1)/2*z;
if((int)w==x) printf("0\n");
else printf("1\n");
尼姆博弈
m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.例如5堆 5,7,8,9,10先取者胜,先取者第1次取时可以从有8个的那一堆取走7个剩下1个,也可以从有9个的中那一堆取走9个剩下0个,也可以从有10个的中那一堆取走7个剩下3个.
1.如果每堆石子的个数异或之后得到一个数k,如果k是0则先手必败
2.如果每堆石子的数量a异或这个k之后得到的石子数量p小于原先这堆石子的数量,即p<a,则获胜策略就是这一堆取出a-p个石子
for(i=0;i<n;i++)
scanf("%d",&a[i]);
k=a[0];
for(i=1;i<n;i++)
k=k^a[i];
if(!k) printf("No\n");
else
{
printf("Yes\n");
for(i=0;i<n;i++)
{
p=k^a[i];
if(p<a[i])
printf("%d %d\n",a[i],p);//此题是输出还剩多少石子
}
}
巴什博弈
只有一堆m个物品,两个人轮流从这堆物品中取物,规
定每次至少取一个,最多取n个。最后取光者得胜。
m是否是(n+ 1)的倍数,m 是(n + 1)的倍数则先手必败,否则先手必胜
while(~scanf("%d %d",&m,&n))
{
if(m%(n+1)==0) printf("none\n");
else//输出第一次可以拿的物品
{
if(m<=n)
{
if(m==n)
printf("%d\n",n);
else
{
for(i=m;i<n;i++)
{
printf("%d ",i);
}
printf("%d\n",n);
}
}
else
printf("%d\n",m%(n+1));
}
}