您的位置:首页 > 其它

leetcode 每日一题 Nim Game

2016-02-29 15:17 197 查看
题目意思比较简单,就是你和朋友拿桌上的一堆石子,每次可以选择拿1-3颗,拿走最后一颗石子的人将胜利,如你先拿,怎样判断你是否能赢?

题目是最简单的博弈论问题,解决方法是如果桌上石子能被4整除,则必输。如果桌上石子不能被4整除,则有必赢的策略。

class Solution {
public:
bool canWinNim(int n) {
if(n%4==0) return false;
else return true;
}
};


如果可以取得的最大数为m,则n%(m+1)为判断是否能赢的条件。

大牛写法为:

return n & 0x3;


之前的nim游戏是没有规定必须取多少个“石子”的,玩法是,放置3,4,5三列硬币,可以从某一列硬币中取走1~全部,最后拿走的人获胜。

关于这个的策略,人们发现从第一列3个硬币里取走2个,之后可以必胜。

取胜方法可以使用二进制来表示,并做nim加法,引用果壳的文章如下:
http://www.guokr.com/blog/777525/
用Nim的方法来做加法运算

秘密就是把堆的大小用二进制数来表示(我假设读这篇文章的人都有一定的数学功底,只要稍微懂点电脑应该懂得二进制)。得到这个取胜秘密的取决于把堆的大小写成二进制形式,接着把这些数字加起来——但是别用一般的加法运算,准确的方法应该叫做Nim加法(Nim addition)。

为了准确的使用Nim加法加一些给定的二进制数,你先把它们排成行的写下来,就像你要做的加法运算一样。接着你轮流看每一列。如果1s的个数是奇数个,在它下面写一个1;如果偶数个,写个0.对每一列都进行这样的操作,得到的就是Nim加法的结果。

作为例子,让我们用Nim加运算加10,11和100(十进制下分别为2,3,4):

10

11

100

——

101

这个被称为Nim和(Nim sum)的结果是101。Nim加法和普通加法和普通加法不同在于:二进制的101表示十进制5,和原来那些数字之和2+3+4=9不相等。

谁赢了?

当Charles Bouton分析了这个Nim游戏,他分析出了两个两个取得获胜策略的关键事实。

事实一:假设轮到你行动了,这时堆里的Nim和为0。这样不管你怎么做,你动作后的Nim和不会等于0.

事实二:假设轮到你行动了,这时堆里的Nim和不为0。但是可以保证的是,存在一种取法能在你行动后的堆的Nim和为0。

其实nim加法等同于二进制加法中的【异或】操作。

Nim加法
输入输出
111+1=0
101+0=1
010+1=1
000+0=0

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: