洛谷 P4136:谁能赢呢?← 棋盘配对博弈(多米诺覆盖博弈)

【题目来源】
https://www.luogu.com.cn/problem/P4136

【题目描述】
小明和小红经常玩一个博弈游戏。给定一个 n×n 的棋盘,一个石头被放在棋盘的左上角。他们轮流移动石头。每一回合,选手只能把石头向上,下,左,右四个方向移动一格,并且要求移动到的格子之前不能被访问过。谁不能移动石头了就算输。
假如小明先移动石头,而且两个选手都以最优策略走步,问最后谁能赢?

【输入格式】
输入文件有多组数据。
输入第一行包含一个整数 n,表示棋盘的规模。
当输入 n 为 0 时,表示输入结束。

【输出格式】
对于每组数据,如果小明最后能赢,则输出 Alice,否则输出 Bob,每一组答案独占一行。​​​​​​​

【输入样例】
2
0​​​​​​​

【输出样例】
Alice​​​​​​​

【数据范围】
对于 20% 的数据,保证 1≤n≤10;
对于 40% 的数据,保证 1≤n≤1000;
对于 100% 数据,保证 1≤n≤10000。

【算法分析】
● 采用棋盘配对博弈(多米诺覆盖博弈)分析:
(1)n 为偶数:整张 n*n 棋盘可以完美被若干 1*2 骨牌铺满。
先手随便走入某一块骨牌的其中一格,后手都可以走到同一块骨牌剩下的另一格。
无论先手怎么走,后手永远有格子可走,最终先手一定会先无路可走 → 先手败,后手必胜。
(2)n 为奇数:去掉起点格子后,剩余棋盘恰好可以被 1*2 骨牌完美覆盖。
先手第一步占据中心 / 起点后,后手走入任意骨牌一格,先手都能对应走到骨牌另一格,后手率先无路可走 → 后手败,先手必胜。
简化判定规则:n为偶数,先手赢;n为奇数,后手赢。

【算法代码】

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

int main() {
    int n;
    while(cin>>n && n) {
        if(n%2==0) cout<<"Alice\n";
        else cout<<"Bob\n";
    }
    return 0;
}

/*
in:
2
0

out:
Alice
*/



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

 

posted @ 2026-08-08 07:16  Triwa  阅读(2)  评论(0)    收藏  举报