P4279 [SHOI2008]小约翰的游戏
题目描述
小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有(n)堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不取,我们规定取到最后一粒石子的人算输。 小约翰相当固执,他坚持认为先取的人有很大的优势,所以他总是先取石子,而他的哥哥就聪明多了,他从来没有在游戏中犯过错误。小约翰一怒之前请你来做他的参谋。自然,你应该先写一个程序,预测一下谁将获得游戏的胜利。
输入输出格式
输入格式:
本题的输入由多组数据组成,第一行包括一个整数(T),表示输入总共有(T)组数据((T≤500))。 每组数据的第一行包括一个整数(N)((N≤50)),表示共有(N)堆石子,接下来有(N)个不超过(5000)的整数,分别表示每堆石子的数目。
输出格式:
每组数据的输出占一行,每行输出一个单词。如果约翰能赢得比赛,则输出“John”,否则输出“Brother”,请注意单词的大小写。
说明
对于(40\%)的数据,(T ≤ 250)。 对于(100\%)的数据,(T ≤ 500)。
( t{Anti-SG})
必胜条件
- 游戏(SG ot=0),子游戏存在(SG>1)
- 游戏(SG=0),子游戏不存在(SG>1)
情况2显然,因为最后一个是奇数堆就输了。
情况1可以从普通(NIM)的角度思考。
发现只有一个子游戏的(SG)函数大于(1)时可以转到必胜态,往这个状态靠拢就行了。
正经证明不会
Code:
#include <cstdio>
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,mx=0,SG=0;
scanf("%d",&n);
for(int x,i=1;i<=n;i++)
scanf("%d",&x),mx=mx>x?mx:x,SG^=x;
if(mx==1) puts(SG?"Brother":"John");
else puts(SG?"John":"Brother");
}
return 0;
}
2018.12.18