跳转至

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 <= 105

解法

方法一:数学

根据题目描述,每一次行动,玩家都会选择顺时针或者逆时针方向,然后摘一朵鲜花。由于 Alice 先行动,因此当 $x + y$ 为奇数时,Alice 一定会赢得游戏。

因此,鲜花数目 $x$ 和 $y$ 满足以下条件:

  1. $x + y$ 为奇数;
  2. $1 \le x \le n$;
  3. $1 \le y \le m$。

若 $x$ 为奇数,$y$ 一定为偶数。此时 $x$ 的取值个数为 $\lceil \frac{n}{2} \rceil$,$y$ 的取值个数为 $\lfloor \frac{m}{2} \rfloor$,因此满足条件的数对个数为 $\lceil \frac{n}{2} \rceil \times \lfloor \frac{m}{2} \rfloor$。

若 $x$ 为偶数,$y$ 一定为奇数。此时 $x$ 的取值个数为 $\lfloor \frac{n}{2} \rfloor$,$y$ 的取值个数为 $\lceil \frac{m}{2} \rceil$,因此满足条件的数对个数为 $\lfloor \frac{n}{2} \rfloor \times \lceil \frac{m}{2} \rceil$。

因此,满足条件的数对个数为 $\lceil \frac{n}{2} \rceil \times \lfloor \frac{m}{2} \rfloor + \lfloor \frac{n}{2} \rfloor \times \lceil \frac{m}{2} \rceil$,即 $\lfloor \frac{n + 1}{2} \rfloor \times \lfloor \frac{m}{2} \rfloor + \lfloor \frac{n}{2} \rfloor \times \lfloor \frac{m + 1}{2} \rfloor$。

时间复杂度 $O(1)$,空间复杂度 $O(1)$。

1
2
3
4
5
6
7
class Solution:
    def flowerGame(self, n: int, m: int) -> int:
        a1 = (n + 1) // 2
        b1 = (m + 1) // 2
        a2 = n // 2
        b2 = m // 2
        return a1 * b2 + a2 * b1
1
2
3
4
5
6
7
8
9
class Solution {
    public long flowerGame(int n, int m) {
        long a1 = (n + 1) / 2;
        long b1 = (m + 1) / 2;
        long a2 = n / 2;
        long b2 = m / 2;
        return a1 * b2 + a2 * b1;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution {
public:
    long long flowerGame(int n, int m) {
        long long a1 = (n + 1) / 2;
        long long b1 = (m + 1) / 2;
        long long a2 = n / 2;
        long long b2 = m / 2;
        return a1 * b2 + a2 * b1;
    }
};
1
2
3
4
5
func flowerGame(n int, m int) int64 {
    a1, b1 := (n+1)/2, (m+1)/2
    a2, b2 := n/2, m/2
    return int64(a1*b2 + a2*b1)
}
1
2
3
4
5
function flowerGame(n: number, m: number): number {
    const [a1, b1] = [(n + 1) >> 1, (m + 1) >> 1];
    const [a2, b2] = [n >> 1, m >> 1];
    return a1 * b2 + a2 * b1;
}

方法二:数学(优化)

方法一得出的结果为 $\lfloor \frac{n + 1}{2} \rfloor \times \lfloor \frac{m}{2} \rfloor + \lfloor \frac{n}{2} \rfloor \times \lfloor \frac{m + 1}{2} \rfloor$。

如果 $n$ 和 $m$ 都是奇数,那么结果为 $\frac{n + 1}{2} \times \frac{m - 1}{2} + \frac{n - 1}{2} \times \frac{m + 1}{2}$,即 $\frac{n \times m - 1}{2}$。

如果 $n$ 和 $m$ 都是偶数,那么结果为 $\frac{n}{2} \times \frac{m}{2} + \frac{n}{2} \times \frac{m}{2}$,即 $\frac{n \times m}{2}$。

如果 $n$ 是奇数,且 $m$ 是偶数,那么结果为 $\frac{n + 1}{2} \times \frac{m}{2} + \frac{n - 1}{2} \times \frac{m}{2}$,即 $\frac{n \times m}{2}$。

如果 $n$ 是偶数,且 $m$ 是奇数,那么结果为 $\frac{n}{2} \times \frac{m - 1}{2} + \frac{n}{2} \times \frac{m + 1}{2}$,即 $\frac{n \times m}{2}$。

上面四种情况可以合并为 $\lfloor \frac{n \times m}{2} \rfloor$。

时间复杂度 $O(1)$,空间复杂度 $O(1)$。

1
2
3
class Solution:
    def flowerGame(self, n: int, m: int) -> int:
        return (n * m) // 2
1
2
3
4
5
class Solution {
    public long flowerGame(int n, int m) {
        return ((long) n * m) / 2;
    }
}
1
2
3
4
5
6
class Solution {
public:
    long long flowerGame(int n, int m) {
        return ((long long) n * m) / 2;
    }
};
1
2
3
func flowerGame(n int, m int) int64 {
    return int64((n * m) / 2)
}
1
2
3
function flowerGame(n: number, m: number): number {
    return Number(((BigInt(n) * BigInt(m)) / 2n) | 0n);
}

评论