问题:
You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.
Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.
For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.
大意:
你和你的一个朋友玩一个游戏:在一个桌子上有一堆石头,每个人每次可以从中拿1个或2个或3个石头,你和你朋友两个人轮流拿,谁拿走的桌上最后一波石头,谁就赢了。你先拿。
假设你和你的朋友都会采取最佳策略。写一个函数来判断对于给出的一个数量的石头,你会不会赢。
比如说,如果桌上有4个石头,那么你肯定输,无论你先拿1个还是2个还是3个,最后一波石头总是被你朋友拿走的。
思路:
乍一看好像不递归不可能判断出来,但其实演算一下,发现是有规律可行的。
- 首先当石头数量是3个以下时,你肯定会赢。
- 当石头数量为4个时,你肯定输。
- 当石头数量为5、6、7个时,你总是可以拿到桌上只剩4个,那对于你朋友来说,他面对4个石头,上面说了,一定会输,所以你一定会赢。
- 当石头数量是8个时,你不管怎么拿,最终桌上只会剩下5、6、7三种情况,那么此时你朋友面对的就是情况3,他就一定赢,而你一定输。
- 当石头数量是9、10、11时,你总是可以把石头拿到只剩8个,那么此时你朋友面对的就是情况4,那他就一定输,而你一定赢。
……
这样分析一下,规律就出来了,只要你面对的石头数量是4的倍数,那你就一定会输,此外,你全都可以赢,赢面还是很大啊哈哈。代码也呼之欲出了。
代码(C++):
class Solution {
public:
bool canWinNim(int n) {
return n % 4 == 0 ? false : true;
}
};
示例工程:https://github.com/Cloudox/NimGame
合集:https://github.com/Cloudox/LeetCode-Record