题意描述:
你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。
示例:
输入: 4
输出: false
解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。
解题思路:
Alice: 这是什么意思呀 ? 什么
你们是聪明人,每一步都是最优解。
Bob: 哈哈哈, 这是一道博弈论的题目,属于 ACM 竞赛中常见的一类题型,在博弈论的题目里面经常会给出这样的条件。
Alice: 所以要怎么做呢 ?
Bob: 我也不知道,先分析一下吧。
Alice: 那就按照找规律来做吧。假设 A 是先手, 如果 A 能赢得游戏就返回 true
,否则就返回 false
。
石头数目 | A赢得比赛 ? | 策略说明 |
---|---|---|
1 | true | A 直接拿 1 个 |
2 | true | A 直接拿 2 个 |
3 | true | A 直接拿 3 个 |
4 | false | A 无论先拿几个,剩下的都会被B 全部拿走,A 必输 |
5 | true | A 拿走 1 个,剩下4 个 从B 开始,B 必输 , A 必赢 |
6 | true | A 拿走 2 个,剩下4 个 从B 开始,B 必输 , A 必赢 |
7 | true | A 拿走 3 个,剩下4 个 从B 开始,B 必输 , A 必赢 |
8 | false | A 拿走 1或者2或者3 个,剩下7或者6或者5个 都会被B拿的只剩4个,A 必输 |
Bob: 我明白了,只要谁在 游戏的过程中 面临着 有4个石子的情况,他就输了。
Alice: 对,而且两个人都是聪明人,每一步都是最优解,所以在游戏开始之前就能确定是谁输谁赢了。只要是 n % 4 != 0
的时候都是先手赢,否则就是后手赢。
Bob: 😉😉果然还会先下手为强呀。
代码:
Python 方法一:
class Solution:
def canWinNim(self, n: int) -> bool:
return n % 4 != 0
Java 方法一:
class Solution {
public boolean canWinNim(int n) {
return n % 4 != 0;
}
}
易错点:
- 很明显,一堆石头至少得有一个石头,所以 0 % 4 == 0 并不构成一个边界值输入,也就是说没有 输入是 0 的坑。
总结: