zoukankan      html  css  js  c++  java
  • 【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
    "); else printf("John
    ");}
    15         else if(step%2==1) printf("Brother
    ");else printf("John
    ");
    16     }
    17 }
  • 相关阅读:
    一次http请求,谁会先断开TCP连接?什么情况下客户端先断,什么情况下服务端先断?
    nginx.conf详解
    50:树中两个结点的最低公共祖先
    49:把字符串转换为整数
    48:不能被继承的类
    47:不用加减乘除做加法
    46:求1+2+...+n
    45:圆圈中最后剩下的数字
    44:扑克牌顺子
    43:n个骰子的点数
  • 原文地址:https://www.cnblogs.com/wuminyan/p/5204379.html
Copyright © 2011-2022 走看看