AcWing 1318:取石子游戏 ← 巴什博奕(Bash Game)

【题目来源】
https://www.acwing.com/problem/content/1320/

【题目描述】
有一种有趣的游戏,玩法如下:
玩家: 2 人;
道具: N 颗石子;
规则:游戏双方轮流取石子;每人每次取走若干颗石子(最少取 1 颗,最多取 K 颗);石子取光,则游戏结束;最后取石子的一方为胜。
假如参与游戏的玩家都非常聪明,问最后谁会获胜?

【输入格式】
输入仅一行,两个整数 N 和 K。

【输出格式】
输出仅一行,一个整数,若先手获胜输出 1,后手获胜输出 2。​​​​​​​

【输入样例】
23 3

【输出样例】
1

【数据范围】
1≤N≤10^5,1≤K≤N

【算法分析】
● 巴什博弈(Bash game)是一种涉及 2 名玩家的双人博弈,属于公平组合游戏(ICG)的典型例子。 博弈中有一堆总数为 n 的物品,2 名玩家轮流从中拿取物品,每次至少拿 1 件,至多拿 m 件,不能不拿,最终将物品拿完者获胜。
(1)n≤m 时,由于一次最少拿一个,最多拿 m 个,甲可以一次拿完,先手赢。
(2)n=m+1 时,无论甲拿走多少个 (1~m 个),剩下的都多于 1 个且少于或等于 m 个,乙都能一次拿走剩余的石子,后手取胜。

● Bash 博弈胜负判定(每次取 1~m 个,取走最后一个石子的胜)
(1)如果 n%(m+1) == 0,即 n 是 m+1 的整数倍,那么不管甲拿多少(记作 k,其中 1≤k≤m),乙都拿 m+1-k 个,使剩下的永远是 m+1 的整数倍,直到最后的 m+1 个,所以后拿的乙一定赢(后手赢)。
(2)如果 n%(m+1) != 0,即 n 不是 m+1 的整数倍,还有余数 r,那么甲拿走 r 个,剩下的是 m+1 的倍数,这样就转移到了情况(1),相当于甲乙互换,结果是先拿的甲赢(先手赢)。

【算法代码】

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n,m;
    cin>>n>>m;
    if(n%(m+1)!=0) cout<<"1\n";
    else cout<<"2\n";

    return 0;
}

/*
in:23 3
out:1
*/



【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/158802453
 

posted @ 2026-08-07 22:25  Triwa  阅读(5)  评论(0)    收藏  举报