bzoj1022 [SHOI2008]小约翰的游戏John

[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


网上题解写的特别好。。。只是我看不懂而已。。。
自己凭借多年开车经验瞎写的。。。


//全为 1 的时候奇数个 1 先手必败。 
//只有一个大于 1 的时候先手必胜
//也就是说现在要证明有两个及以上大于 1 的时候如果 NIM和 == 0 后手必胜。
//除去特殊情况外所有情况一定能转化到刚好有两个大于 1 
//因为如果只有两堆且他们一样多的时候,显然后手必胜
//也就是说如果说两堆一样多的话就看 1 的个数是奇数还是偶数,如果是奇数则先手胜。
//如果只有两堆但是不一样多的话先手必胜。
//同理可得两堆不一样多就看 1 的个数,偶数则先手胜。
//那么最后的问题就变成了我们要判断有大于两个大于 1 的数的时候转化到上面的情况谁先谁后。
//显然 NIM和 == 0 的时候后手胜利(想一想就知道了) 

/*
综上,先手必胜的条件是:
1.如果全为 1 则有偶数个 1 (NIM和 == 0)
2.只有一个大于 1
3.除上面两种情况以后 NIM和 != 0 
*/ 
#include<bits/stdc++.h>
using namespace std;
int n, x, lin, all;

int main()
{
	int T; scanf("%d", &T);
	while(T--){
		scanf("%d", &n);
		lin = all = 0;
		for(int i = 1; i <= n; ++i){scanf("%d", &x); lin += (x > 1); all ^= x;}
		if(!lin && !all){printf("John\n"); continue;}
		if(lin == 1){printf("John\n"); continue;}
		if(lin > 1 && all){printf("John\n"); continue;}
		printf("Brother\n");
	} 
	return 0;
}

posted @ 2018-11-01 22:01  沛霖  阅读(134)  评论(0编辑  收藏