博弈论

巴什博弈

题意:一堆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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值