E - Misere Nim(反nim博弈,最后一手拿石子的输)

在这里插入图片描述
思路:一般的nim博弈大家都会吧,一般的就是取最后一枚石子的人赢;

先讨论 n 堆石子全部为1的情况:

当 n 为奇数时,先手一定输,后手一定赢

当 n 为偶数时,先手一定赢,后手一定输;

当 n堆 不全部为1的情况:

我们先看一般的nim博弈的必胜态:当前状态为必胜态,先手经最优策略 取过后,就到达必败态也就是平衡态,平衡态只能转移到不平衡态(必胜态),不平衡态经过 某一个途径 可以 转移到平衡态;

当n堆 不全部为1时,当一般的nim博弈的必胜态也就是不一样的nim博弈的必胜态,当前状态为 不平衡态;

先手                 后手             先手                              先手                     后手                          先手

不平衡态 —> 平衡态 —> 不平衡态 —> …–> 不平衡态 —> 不平衡态(下面有解释) --> 平衡态–>

 必胜态            必败态          必胜态                          必胜态               必败态                 必胜态

解释:在这些从 不平衡态 到 平衡态 的 转中,在不一样的nim博弈中,有一个临界情况,一定会出现 从不平衡态到不平衡态,后面这个不平衡态 是 (剩下奇数堆且这奇数堆石子数全部都是1),当前这个状态取的人一定输,也是就后手,所以先手一定赢;具体看代码理解

#include <iostream>
#include <algorithm>
#include <cmath>
#include <ctype.h>
#include <cstring>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <string>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int maxn=1000000;
const ll mod = 1e9+7;
int main(){
	int t;
	int cas=1;
	scanf("%d",&t);
	while(t--)
    {
        int m,sum=0;
        scanf("%d",&m);
        int flag=0,x;
       for(int i = 0;i < m;i ++)
		{
			scanf("%d",&x);
			if(x != 1)
				flag = 1;
			sum ^= x;
		}
		printf("Case %d: ",cas++);
		if(!flag)
		{
			if(m&1) printf("Bob\n");
			else printf("Alice\n");
		}
		else
		{
			if(sum) printf("Alice\n");
			else printf("Bob\n");
		}

    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值