3021. Alice 和 Bob 玩鲜花游戏

题目

Alice 和 Bob 在一个长满鲜花的环形草地玩一个回合制游戏。环形的草地上有一些鲜花,Alice 到 Bob 之间顺时针有 x 朵鲜花,逆时针有 y 朵鲜花。

游戏过程如下:

  1. Alice 先行动。
  2. 每一次行动中,当前玩家必须选择顺时针或者逆时针,然后在这个方向上摘一朵鲜花。
  3. 一次行动结束后,如果所有鲜花都被摘完了,那么 当前 玩家抓住对手并赢得游戏的胜利。

给你两个整数 n 和 m ,你的任务是求出满足以下条件的所有 (x, y) 对:

  • 按照上述规则,Alice 必须赢得游戏。
  • Alice 顺时针方向上的鲜花数目 x 必须在区间 [1,n] 之间。
  • Alice 逆时针方向上的鲜花数目 y 必须在区间 [1,m] 之间。

请你返回满足题目描述的数对 (x, y) 的数目。

示例 1:

输入:n = 3, m = 2 输出:3 解释:以下数对满足题目要求:(1,2) ,(3,2) ,(2,1) 。

示例 2:

输入:n = 1, m = 1 输出:0 解释:没有数对满足题目要求。

提示:

  • 1 <= n, m <= 10^5

解题思路

这道题的本质是一个简单的博弈论问题。解题的关键在于判断谁会拿走最后一朵花

  1. 游戏总步数:游戏的总步数是固定的,等于总的鲜花数量,即 x + y
  2. 玩家与步数奇偶性
    • Alice是先手,她总是在第1、3、5、...(奇数)步行动。
    • Bob是后手,他总是在第2、4、6、...(偶数)步行动。
  3. 获胜条件:谁拿走最后一朵花,谁就获胜。这意味着,如果总步数 x + y 是一个奇数,那么最后一个行动的玩家必定是 Alice。如果总步数 x + y 是一个偶数,那么最后一个行动的玩家必定是 Bob。
  4. Alice 必胜的条件:为了让 Alice 必胜,她必须是拿走最后一朵花的玩家。因此,游戏的总步数 x + y 必须是奇数

现在问题就转化为了:在给定的范围 1 <= x <= n1 <= y <= m 内,找到所有使得 x + y 为奇数的数对 (x, y) 的数量。

根据整数的奇偶性(也称为宇称)运算法则:

  • 奇数 + 奇数 = 偶数
  • 偶数 + 偶数 = 偶数
  • 奇数 + 偶数 = 奇数
  • 偶数 + 奇数 = 奇数

因此,要使 x + y 为奇数,必须满足以下两种情况之一:

  1. x 是奇数,同时 y 是偶数。
  2. x 是偶数,同时 y 是奇数。

这两种情况是互斥的,所以我们只需要分别计算这两种情况下的数对数量,然后相加即可。

具体代码

class Solution {
public:
    long long flowerGame(int n, int m) {
        
        // 奇数+奇数=偶数,偶数+偶数=偶数,奇数+偶数=奇数

        long long odd1 = (n + 1) / 2;
        long long odd2 = (m + 1) / 2;
        long long even1 = n / 2;
        long long even2 = m / 2;

        return odd1 * even2 + odd2 * even1;
        
    }
};