[超级码力在线编程大赛初赛(三)] 字符串游戏 反Nim博弈

题目链接:字符串游戏
题意

现在有一个字符串s,每个人可以选择字符串中的某一个区间和一种字符,删除这个区间内的所有该字符(需要删除字符的数量至少为1)。从Alice开始,Alice与Bob轮流进行进行这个操作,若在某个玩家删除前,字符串已经为空,则该玩家获胜。
假设Alice和Bob都会按照其最优的解法删除,Alice想知道,她是否可以获胜。

题解

我们来分析这道题,这个删除操作其实可以看作至少删除一个同种字符,最多无上限甚至可以全部删除。
现在Alice先手,最后删除完的人是输而不是赢。问谁能获胜。

看完这个题想必大家心中已经有一个模型——Nim博弈。
相同的字符可以看为一堆石子,每次我们只能从同堆中取至少一个石子,最多可以全部取完。不同的是最后取完的是输而不是赢。

通过画出状态图,我们能得出这种反Nim博弈类型的题影响的只有石子全为1的情况,剩下的是不影响的。

  1. 当石子全为1,很明显如果能整除2,那么先手胜;否则,后手胜。
  2. 当石子至少有一个不为1时,判断条件和Nim博弈相同,异或石堆,为0时后手胜;否则,先手胜。

我们从最后的状态考虑,每个石堆的状态在最后都能转化为两种情况:1.取走大于1的那一堆,其余(n-1)每堆石子全为1。2.n堆石子数全为1。
所以在状态图中,一定会有一层出现上述两种情况。

反Nim博弈在石子全为1时的必胜态恰恰与Nim博弈相反,所以在Nim博弈的状态图中有一层出现上述两种情况时,在反Nim博弈中胜变负、负变胜,对于上一层状态,很明显是仍然不变的。所以当至少有石子不为1时,判断条件和Nim博弈相同。

在这里插入图片描述

代码
class Solution {
public:
	/**
	 * @param s: a string for this game 
	 * @return: return whether Alice can win this game
	 */
	map<char,int> book;
	bool stringGame(string &s) {
		// Write your code here.
		book.clear();
		int n=s.length();
		for(int i=0;i<n;i++) book[s[i]]++;
		int res=0,cnt=0;
		for(int i=0;i<26;i++) 
		{
			res^=book['a'+i];
			if(book['a'+i]==1) cnt++;
		}
		if(cnt==n)
		{
			if(cnt%2==0) return true;
			else return false;
		}
		else
		{
			if(res) return true;
			else return false;
		}
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值