题目
Alice 和 Bob 在一个长满鲜花的环形草地玩一个回合制游戏。环形的草地上有一些鲜花,Alice 到 Bob 之间顺时针有 x
朵鲜花,逆时针有 y
朵鲜花。
游戏过程如下:
- Alice 先行动。
- 每一次行动中,当前玩家必须选择顺时针或者逆时针,然后在这个方向上摘一朵鲜花。
- 一次行动结束后,如果所有鲜花都被摘完了,那么 当前 玩家抓住对手并赢得游戏的胜利。
给你两个整数 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
解题思路
这道题的本质是一个简单的博弈论问题。解题的关键在于判断谁会拿走最后一朵花。
- 游戏总步数:游戏的总步数是固定的,等于总的鲜花数量,即
x + y
。 - 玩家与步数奇偶性:
- Alice是先手,她总是在第1、3、5、...(奇数)步行动。
- Bob是后手,他总是在第2、4、6、...(偶数)步行动。
- 获胜条件:谁拿走最后一朵花,谁就获胜。这意味着,如果总步数
x + y
是一个奇数,那么最后一个行动的玩家必定是 Alice。如果总步数x + y
是一个偶数,那么最后一个行动的玩家必定是 Bob。 - Alice 必胜的条件:为了让 Alice 必胜,她必须是拿走最后一朵花的玩家。因此,游戏的总步数
x + y
必须是奇数。
现在问题就转化为了:在给定的范围 1 <= x <= n
和 1 <= y <= m
内,找到所有使得 x + y
为奇数的数对 (x, y)
的数量。
根据整数的奇偶性(也称为宇称)运算法则:
- 奇数 + 奇数 = 偶数
- 偶数 + 偶数 = 偶数
- 奇数 + 偶数 = 奇数
- 偶数 + 奇数 = 奇数
因此,要使 x + y
为奇数,必须满足以下两种情况之一:
x
是奇数,同时y
是偶数。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;
}
};