Leetcode每日一题(20200724)

  • Post author:
  • Post category:其他

今日题目

T1025 除数博弈

题目描述

爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。

最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:

选出任一 x,满足 0 < x < N 且 N % x == 0 。
用 N – x 替换黑板上的数字 N 。
如果玩家无法执行这些操作,就会输掉游戏。

只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。

示例 1:

输入:2
输出:true
解释:爱丽丝选择 1,鲍勃无法进行操作。
示例 2:

输入:3
输出:false
解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。

提示:

1 <= N <= 1000

标签

博弈

解析

本题的唯一问题是如何通过数字判断胜利条件。显然对于任意奇数N,如果N是素数,则x只能取1,N-x为偶数;如果N是合数,由N是奇数,可知N的因子都是奇数,即x只能取奇数,N-x为偶数。总之,N是奇数时,N-x一定是偶数。

那么,如果N是偶数呢?这时我们有两种选择:N-x是奇数,或N-x是偶数。通过上一段我们可以看出,如果N-x是奇数,则再次轮到我们操作时,N一定是偶数。但如果N-x是偶数,这个选择的权利就交到了对方手上。另外,从示例中也可以看出,N=2时我们是必胜的。

既然N=2是必胜的,那么接下来的关键,就变成了,如何将N>2的情况,转化成N=2的情况。

对于N是偶数的情况,如果我们令N-x为奇数,则N经过两次减法、再次轮到我们操作时,一定还是偶数。这样下去,一定可以得到N=2的情况,此时我们必败。

对于N是奇数的情况,N-x只能为偶数,此时等同于对方N为偶数的情况,此时我们必败。

因此,只需要通过判断N是奇数还是偶数,就可以得到正确的结果。

当然,如果追求更短的用时,你甚至可以使用位运算。显然N为偶数时二进制的最后一位必为0,此时需要返回True,而N为奇数时二进制的最后一位为1,返回False。使用位运算时,我们只需要返回not(N&1)即可。

C++解法

class Solution {
public:
    bool divisorGame(int N) {
        if(N%2)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
};

python解法

class Solution:
    def divisorGame(self, N: int) -> bool:
        return not (N & 1)

备注

耐心分析很重要


版权声明:本文为hywo_0015原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。