Submit: 3134 Solved: 2003
[Submit][Status][Discuss]
Description
小約翰經常和他的哥哥玩一個非常有趣的遊戲:桌子上有n堆石子,小約翰和他的哥哥輪流取石子,每個人取
的時候,可以隨意選擇一堆石子,在這堆石子中取走任意多的石子,但不能一粒石子也不取,我們規定取到最後一
粒石子的人算輸。小約翰相當固執,他堅持認為先取的人有很大的優勢,所以他總是先取石子,而他的哥哥就聰明
多了,他從來沒有在遊戲中犯過錯誤。小約翰一怒之前請你來做他的參謀。自然,你應該先寫一個程式,預測一下
誰將獲得遊戲的勝利。
Input
本題的輸入由多組資料組成第一行包括一個整數T,表示輸入總共有T組資料(T≤500)。每組資料的第一行包
括一個整數N(N≤50),表示共有N堆石子,接下來有N個不超過5000的整數,分別表示每堆石子的數目。
Output
每組資料的輸出佔一行,每行輸出一個單詞。如果約翰能贏得比賽,則輸出“John”,否則輸出“Brother”
,請注意單詞的大小寫。
Sample Input
2
3
3 5 1
1
1
3
3 5 1
1
1
Sample Output
John
Brother
Brother
HINT
裸的Anti-Nim遊戲
直接上定理
先手必勝的條件
所有堆的石子數都為1且遊戲的SG值為0
有些堆的石子數大於1且遊戲的SG值不為0
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; const int MAXN=1e6+10,INF=1e9+10; inline char nc() { static char buf[MAXN],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++; } inline int read() { char c=nc();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();} return x*f; } int a[MAXN]; main() { #ifdef WIN32 freopen("a.in","r",stdin); #else #endif int QWQ=read(); while(QWQ--) { int N=read(),one=0,allone=1,ans=0; for(int i=1;i<=N;i++) { a[i]=read(); if(a[i]!=1) allone=0; if(a[i]>1) one=1; ans=ans^a[i]; } if( (ans==0&&allone) || (ans!=0&&one) ) printf("John\n"); else printf("Brother\n"); } return 0; }