题目描述
你和一个朋友玩Nim游戏:桌上有一堆石子,每次你们可以拿走1-3枚石子,交替进行。拿走最后一枚石子的玩家获胜。你是先手。
你们两名玩家都非常聪明,每次都会选择最优玩法。请编写一个函数,判断给定 n 枚石子时,你能否获胜。
样例
输入:4
输出:false
解释:一共有4枚石子,你必败。不管第一次你取多少石子,
第二次你的对手都可以取走剩下的所有石子。
算法
(博弈论) O(1)
如果 n 能被 4 整除,则不论每次你取多少石子,不妨设是 x,你的对手可以取 4−x 枚石子。那么最后一枚石子一定被对手取走,你必败;
如果 n 不能被 4 整除,则你第一次取走 n%4 枚石子,然后剩下的石子数就是 4 的倍数,按上一种情况的讨论,你的对手必败,你必胜。
在C++中,n%4
可以用位运算计算,时间效率高一些,n%4 = n&3
。
时间复杂度分析:只有一次位运算,时间复杂度是 O(1)。
C++ 代码
class Solution {
public:
bool canWinNim(int n) {
return n&3;
}
};