洛谷 P4279:[SHOI2008] 小约翰的游戏 ← 反Nim博弈

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

【题目描述】
小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有 n 堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不取,我们规定取到最后一粒石子的人算输。
小约翰相当固执,他坚持认为先取的人有很大的优势,所以小约翰总是先取石子,而他的哥哥就聪明多了,他从来没有在游戏中犯过错误。小约翰一怒之前请你来做他的参谋。自然,你应该先写一个程序,预测一下谁将获得游戏的胜利。

【输入格式】
本题的输入由多组数据组成,第一行包括一个整数 T(1≤T≤500),表示输入总共有 T 组数据。
每组数据的第一行包括一个整数 N(1≤N≤50),表示共有 N 堆石子,接下来有 N 个不超过 5000 的整数,分别表示每堆石子的数目。

【输出格式】
对于每组数据,如果约翰能赢得比赛,则输出 John,否则输出 Brother,请注意单词的大小写。

【输入样例】
2
3
3 5 1
1
1​​​​​​​

【输出样例】
John
Brother​​​​​​​

【数据范围】
对于 40% 的数据,T≤250;
对于 100% 的数据,T≤500。

【算法分析】
● 反 Nim 博弈(Anti-Nim Game)是经典 Nim 博弈的变体,规则为“取走最后一个石子者输”。先手必胜当且仅当:‌(1)所有堆的石子数量 a1,a2,a3,⋯,an 均为 1 且堆数为偶数‌,或‌(2)至少有一堆石子的数量大于 1 ,且全体石子堆构成的全局异或和 S=a1⊕a2⊕a3⊕⋯⊕an 非零‌

● 本题是典型的反 Nim 博弈(取最后一颗石子者落败),设全局异或和为 xor_sum,判定规则如下:
1. 所有堆的石子数量都为 1:
   - 堆数为偶数:先手胜;
   - 堆数为奇数:先手败。
2. 存在至少一堆石子的数量 > 1:
   - xor_sum ≠ 0 → 先手必胜;
   - xor_sum = 0 → 先手必败。

【算法代码】

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

int T,n,x;
bool win;

int main() {
    cin>>T;
    while (T--) {
        cin>>n;
        int xor_sum=0,cnt=0;
        for(int i=1; i<=n; i++) {
            cin>>x;
            xor_sum^=x;
            if(x==1) cnt++;
        }

        if(cnt==n) win=(n%2==0);
        else win=(xor_sum!=0);
        cout<<(win?"John":"Brother")<<"\n";
    }
    return 0;
}

/*
in:
2
3
3 5 1
1
1

out:
John
Brother
*/



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



 

posted @ 2026-08-06 10:53  Triwa  阅读(4)  评论(0)    收藏  举报