尼姆博弈——Nimm Game

本文介绍了一个基于尼姆博弈的游戏——Georgia和Bob之间的对决,并详细解释了如何通过将棋子位置转化为尼姆博弈中的堆来判断游戏胜负。文章还提供了一段C++代码,用于根据给定的棋子初始位置预测赢家。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

三大基础博弈(必看 未看)(转)

尼姆博弈(Nimm Game):

尼姆博弈指的是这样一个博弈游戏:有任意堆物品,每堆物品的个数是任意的,双方轮流从中取物品,每一次只能从一堆物品中取部分或全部物品,最少取一件,取到最后一件物品的人获胜。

结论:把每堆物品数全部异或起来,如果得到的值为0,那么先手必败,否则先手必胜。

题目:Georgia and Bob
【题意】
游戏规则如下:
1.每人每次可以且只能移动一个棋子
2.每次移动棋子的格子数不限
3.只能向左移动棋子
4.移动过程中不能覆盖或越过其它棋子
5.当谁没有棋子可以移动时,就输了
6.两人轮流移动石子,女士优先,Georigia总是先移动
7.最左端所在坐标为0,亦即放在1位置的棋子不能再往左移
假设两人一样聪明,给定棋子的初始位置,判断谁将是赢家。
【分析】
我们把棋子按位置升序排列后,从后往前把他们两两绑定成一对。如果总个数是奇数,就把最前面一个和边界(位置为0)绑定。

在同一对棋子中,如果对手移动前一个,你总能对后一个移动相同的步数,所以一对棋子的前一个和前一对棋子的后一个之间有多少个空位置对最终的结果是没有影响的。

于是我们只需要考虑同一对的两个棋子之间有多少空位。

这样一来就成了N堆取石子游戏了,这就变成了最裸的Nimm Game问题了,套用模型即可.

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int N,a[1003]={},sum=0;
        scanf("%d",&N);
        for(int i=1;i<=N;i++){
            scanf("%d",&a[i]);
        }
        sort(a+1,a+N+1);
        if(N%2==0){///偶数个棋子的情况
            for(int k=1;k<=N;k=k+2){
                sum^=(a[k+1]-a[k]-1);
            }
        }
        else{///奇数个棋子的情况
            sum=a[1]-1;
            for(int k=2;k<=N;k=k+2){
                sum^=(a[k+1]-a[k]-1);
            }
        }
        if(sum)
            printf("Georgia will win\n");
        else
            printf("Bob will win\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值