bzoj 1022 [SHOI2008]小约翰的游戏John - anti Nim

1022: [SHOI2008]小约翰的游戏John

Time Limit: 1 Sec  Memory Limit: 162 MB

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
 
Nim 游戏的拓展
 
这道题的结论就是:

1、 所有石子堆的数目都为1,则当N为偶数时先手必胜,否则后手必胜。

2、 只有一堆石子的数目大于1,先手必胜。

至少有2堆石子的数目大于1,这时如果异或值不为0,先手必胜,否则后手必胜。

 

 

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 const int MAXN = 5010;
 6 int N;
 7 int flag = 0;
 8 int a[MAXN]; 
 9 int ans;
10 inline int read()
11 {
12     int x = 0, w = 1; char ch = 0;
13     while(ch < '0' || ch > '9') {
14         if(ch == '-') {
15             w = -1;
16         }
17         ch = getchar();
18     }
19     while(ch >= '0' && ch <= '9') {
20         x = x * 10 + ch - '0';
21         ch = getchar();
22     }
23     return x * w;
24 }
25 int T;
26 int main()
27 {
28     //freopen("john10.in", "r", stdin);
29 //    freopen("t.out", "w" , stdout);
30     T = read();
31     while(T--) {
32         N = read();
33         ans = 0, flag = 0; 
34         for(int i = 1; i <= N; i++) {
35             a[i] = read();
36             if(a[i] > 1) {
37                 flag = 1;
38             }
39             ans = a[i] ^ ans;
40         }
41         if((!flag && ans == 0) || (flag && ans != 0)) {
42             printf("John\n");
43         } else {
44             printf("Brother\n");
45         }
46     }
47     return 0;
48 }
49 
50 /*
51 2 
52 
53 3 
54 
55 3 5 1 
56 
57 1 
58 
59 1
60 */
View Code

 

 

 

posted @ 2018-02-12 11:44  大财主  阅读(138)  评论(0编辑  收藏  举报