LeetCode 292. Nim Game 题解(C++)
题目描述
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.
思路
超时解法
- 看到这道题的第一想法是使用递归进行解答,在确定了stone数为1,2,3,5,6,7时都能赢得游戏,stone数为4时游戏会输后,在递归函数的入口进行了判断
- 接下来,分别对取1,2,3块石头的情况进行递归,所得的bool值是对方能不能取胜的结果,所以需要进行取反
- 使用上述算法submit的结果是在n=35时超时
最佳解法
- 其实这道题是有规律的,在n分别为1,2,3时胜利,n等于4时失败,当n分别为5,6,7时,此时你只需取1,2,3块stone,则对方取时n都为4,此时对方失败;同理,当n等于8时,无论你取1,2,3块stone,对方都可以在7,6,5块stone里取,按照上面的推理,此时对方胜利…接下去可推得只要n为4的倍数,对方就取得胜利,否则我方获得胜利,所以这道题只需要一行代码便可以解决。
代码
超时解法
class Solution
{
public:
bool canWinNim(int n)
{
if (n <= 3 || n == 5 || n == 6 || n == 7)
{
return true;
}
if (n == 4)
{
return false;
}
bool takeOne = canWinNim(n - 1);
bool takeTwo = canWinNim(n - 2);
bool takeThree = canWinNim(n - 3);
return (!takeOne) || (!takeTwo) || (!takeThree);
}
};
最佳解法
class Solution
{
public:
bool canWinNim(int n)
{
return (n % 4 != 0);
}
};