题目链接

【模板】巴什博弈

题目描述

有一堆石子,共 个。Alice 和 Bob 两位玩家轮流行动,Alice 先手。每人每次可以从堆中取走 个石子。取走最后一个石子的一方获胜。假设双方都采取最优策略,判断先手能否必胜。

解题思路

这是最基础、最经典的公平组合博弈模型——巴什博弈 (Bash Game)

这类问题的核心是寻找游戏中的“必胜态”与“必败态”。一个局面是“必败态”,指的是无论当前玩家如何操作,都会将一个“必胜态”留给对手。反之,如果一个局面至少存在一种走法,能够将“必败态”留给对手,那么这个局面就是“必胜态”。

  1. 寻找关键局面 让我们思考一个特殊情况:如果当前石子数量为 ,轮到你操作,会发生什么?

    • 你必须取走 个石子,其中
    • 取完后,剩余的石子数量为 ,这个数量的范围是
    • 此时,你的对手面对 个石子,他可以一次性将它们全部取走,从而获胜。
    • 因此,当石子数量为 时,轮到的玩家必输。这是一个关键的必败态
  2. 推广规律 既然 是一个必败态,那么双方的最优策略就是尽可能地将这个局面(或其倍数)留给对方。

    • 不是 的倍数时: 设 ,其中 。 先手 Alice 可以非常聪明地只取走 个石子。这是一个合法的操作,因为 。 操作后,剩下 个石子。现在轮到 Bob,他面对的是一个 的倍数。

    • 的倍数时: 设 。 先手 Alice 必须取走 个石子,其中 。 操作后,剩下 个石子,这个数量显然不再是 的倍数。 现在轮到 Bob,他面对的就是上面一种情况。Bob 同样可以取走余数,将一个更小的 的倍数还给 Alice。

  3. 最终结论 这个过程不断重复。如果初始石子数 的倍数,那么 Alice 每次都会破坏这个倍数关系,而 Bob 总能将其修复。最终,Alice 将会面对 个石子并输掉比赛。反之,如果初始 不是 的倍数,Alice 就能在第一步掌控主动权,迫使 Bob 总是面对 的倍数。

    • 如果 ,则先手必败(Bob 胜)。
    • 如果 ,则先手必胜(Alice 胜)。

代码

#include <iostream>

using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin >> t;
    while (t--) {
        int n, m;
        cin >> n >> m;
        if (n % (m + 1) == 0) {
            cout << "NO" << endl;
        } else {
            cout << "YES" << endl;
        }
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while (t-- > 0) {
            int n = sc.nextInt();
            int m = sc.nextInt();
            if (n % (m + 1) == 0) {
                System.out.println("NO");
            } else {
                System.out.println("YES");
            }
        }
    }
}
import sys

def solve():
    t_str = sys.stdin.readline()
    if not t_str:
        return
    t = int(t_str)
    for _ in range(t):
        line = sys.stdin.readline()
        if not line:
            break
        n, m = map(int, line.split())
        if n % (m + 1) == 0:
            print("NO")
        else:
            print("YES")

solve()

算法及复杂度

  • 算法: 博弈论 (巴什博弈)
  • 时间复杂度: 对于每组测试数据,我们只进行了一次取模和判断操作,时间复杂度为 。总的时间复杂度为 ,其中 是测试数据的组数。
  • 空间复杂度: 没有使用额外的存储空间,空间复杂度为