码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1022: [SHOI2008]小约翰的游戏John(博弈SG-nim游戏)

时间:2018-03-01 23:29:05      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:line   ret   span   www.   algorithm   color   font   strong   cst   

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

题目:传送门 

题目大意:

   一道反nim游戏,即给出n堆石子,每次可以取完任意一堆或一堆中的若干个(至少取1),最后一个取的LOSE 

题解:

   一道很不错的题目啊,感觉可以作为一道很好的入门题

   读前一戳:博弈论文 && POPQQQ大佬%%%

   大体要分为三种情况来讨论:

   1、全是为1的石子堆,如有偶数堆则先手胜,反之后手胜

   2、有两堆相同的石子且都不为1(后手获胜的几率很大):
        那么如果先手将其中一堆取剩1,那么后手就可以将另一堆取完,此时后手胜

        如果先手将其中一堆取完,那么后手就可以将另一堆取剩1,还是后手胜

                如果先手仅拿走其中一堆的一部分,那么后手可以进行相同的操作,将另一堆也拿走相同的数量(这是情况又回到了上面两种)

   3、如果异或和不为0,那么对于一般的nim游戏一定可以将石子堆变成仅剩两堆相同的(平衡状态xor=0),这时又如上面所述了

  总结:

   如果全是石子数为1,异或和为0则先手胜,反之后手胜

   如果有不为1的,异或和不为0则先手胜,反之后手胜

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 int T,n;
 8 int main()
 9 {
10     scanf("%d",&T);
11     while(T--)
12     {
13         scanf("%d",&n);int x,ans=0;bool flag=true;
14         for(int i=1;i<=n;i++)
15         {
16             scanf("%d",&x);ans^=x;
17             if(x!=1)flag=false;
18         }
19         if(flag==true)
20         {
21             if(ans==0)printf("John\n");
22             else printf("Brother\n");
23         }
24         else
25         {
26             if(ans==0)printf("Brother\n");
27             else printf("John\n");
28         }
29     }
30     return 0;
31 }

bzoj1022: [SHOI2008]小约翰的游戏John(博弈SG-nim游戏)

标签:line   ret   span   www.   algorithm   color   font   strong   cst   

原文地址:https://www.cnblogs.com/CHerish_OI/p/8490519.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!