【BZOJ 1022】 [SHOI2008]小约翰的游戏John

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

Sample Output

John
Brother

HINT

 

【数据规模】

对于40%的数据,T ≤ 250。

对于100%的数据,T ≤ 500。

 

博弈论

考虑特殊情况

每堆石子都是1时,如果堆数是奇数brother win,比如只有一堆石子且为1

考虑偶数堆相同的石子,此时xor值为0,此时先取的人可以取走一堆,后取得人也取走一堆变成少两堆的状态,如此往复

知道最后还有两堆,先手取1堆,后手取到只剩一个,由此当sg==0时后手胜

当sg!=0时,先手胜,因为先手必然能找到一中方法使sg==0

 1 #include<cstdio>
 2 int T,n;
 3 int main(){
 4     scanf("%d",&T);
 5     while(T--){
 6         int num=0,x,step=0;bool flag=0;
 7         scanf("%d",&n);
 8         for(int i=1;i<=n;i++) {
 9             scanf("%d",&x),num^=x;
10             if (x>1)flag=1;
11             step++;
12         }
13         if(flag){
14             if(num==0) printf("Brother\n"); else printf("John\n");}
15         else if(step%2==1) printf("Brother\n");else printf("John\n");
16     }
17 }

 

你可能感兴趣的:(【BZOJ 1022】 [SHOI2008]小约翰的游戏John)