题目: 你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
示例:
输入: 4
输出: false
解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
思路:
- 如果n小于4,则一定能赢
- 如果n等于4,则一定输
- 如果n大于四,对于从4到n的所有数依次遍历,对每个数维护其前面三个数的输赢情况,如果其前面三个数均为赢,则该数为输,如果前面三个数中存在输,则该数为赢。
代码:
class Solution(object):
def canWinNim(self, n):
"""
:type n: int
:rtype: bool
"""
win = []
loss = []
if n<4:
return True
else:
win = [1,2,3]
for i in range(4,n+1):
for j in range(1,4):
if i-j in loss:
win.append(i)
break
if not i in win:
loss.append(i)
if len(loss) == 0:
del win[0]
elif len(win) == 0:
del loss[0]
elif win[0] < loss[0]:
del win[0]
else:
del loss[0]
if n in win:
return True
else:
return False
结果:内存超弦,测试用例是1348820612!
其实离真相只有一步之遥!如果在纸上依次从1写下去就会发现,只有在n是4的整数倍的时候才会false,可以这么理解,如果到某个人拿石头的时候,如果石头数量是4的倍数,则这个人一定输了,因为不管他拿几个(比如i个),对方只要拿4-i个,就一定能保证拿到最后一个。也就是说,如果一开始n是4的倍数,那一定输了,否则,只要拿若干个使得剩下的数量为4的倍数,就一定能赢。
代码:就不贴了