巴什博弈
题意:一堆n个物品,两人轮流取,每次取1至m个,最后取完者胜。
可以发现,两人每次取的时候,两人所取物品之和最多可以为(1+m)个,也就是说,游戏每进行一轮,物品可减少(m+1)个,所以,要想先取到第n个物品,那么他就要先取出n-(m+1)物品,再下一次为 n-2(m+1),依次类推.......
因此,可以发现r=n%(m+1) ,如果r==0的话,则后取物品的人获胜,反之,则先取物品的人获胜。
代码入下:
#include<stdio.h>
int main(){
int n,m;//m表示可以取(1~m)个物品数,n表示物品的总数
scanf("%d%d",&n,&m);
if((n%(m+1)))
printf("先手赢\n");
else
printf("后手赢");
return 0;
}
尼姆博弈
题意:有任意堆物品,两人任意从其中一堆取走任意个物品,至少取走一个物品,最后取完物品的人赢。
解决办法:将所有堆得物品数进行异或运算,如果结果为0,则后取的赢,否则,先取的赢。
代码如下:
#include<stdio.h>
int main()
{
int n,ans,temp;
while(~scanf("%d",&n))
{
temp=0;
for(int i=0;i<n;i++)
{
scanf("%d",&ans);
temp^=ans;
}
if(temp==0)
printf("后手赢\n");
else
printf("先手赢\n");
}
return 0;
}
威佐夫博弈
题意:有两堆物品,两人从其中一堆物品中取任意个物品,或者同时从两堆中取出相同数量的物品,取完所有物品的人赢。
解题方法:假设两堆物品中的物品数分别位(x,y)(注:x<y),则z=y-x,记w=(int)( (sqrt(5)+1)/2*z ) ,如果x==w,后手赢,否则先手赢。
代码入下:
#include<stdio.h>
#include<math.h>
#include<iostream>
using namespace std;
int main(){
long long T;
scanf("%I64d",&T);
while(T--){
long long A,B;
scanf("%I64d",&A);
scanf("%I64d",&B);
long long a=min(A,B);
long long b=max(A,B);
long long z=b-a;
long long w=(long long)(((sqrt(5)+1)/2)*z);
if(w==a)
printf("B\n");
else
printf("A\n");
}
return 0;
}