ZOJ3113_John

这个题目是一个典型的Anti_Sg。我也不知道为什么这么叫,呵呵,反正大家都这么叫,而且我也是听别人说,看别人的日志自己才知道的。

题目的意思是给你不同颜色的石子,每次可以去一种颜色的石子若干个(至少为1),取完最后一颗石子的人获胜。

由于对于同一种颜色的石子来说,可取的数量是任意的,所以在这个题目里面一个数所对应的SG函数值就是本身。

首先我们定义一个数k为当前每一堆石子数量的异或值。

对于必胜策略,有两种可能的情况。

一。初始状态下,所有的石子堆中石子的个数全为1,且堆数为偶数。

二。初始状态下,石子堆中石子的个数不全为1,且k不为0。

对于第一种状态是显然的。下面来讨论一下第二种状态吧。

初始状态下,因为k!=0,那么先手的人总可以在某一堆中取出一定的数量(根据异或的性质,这是一定存在的哦,写成二进制自己理解一下吧),使得k=0,这样后手的人无论怎么取,取后的结果一定不为0。

每次取完的效果都是先手的人使得k由非零变零(也包括最后一次),后手的人有零变非零。所以先手必胜。

到这里题目瞬间变水了。 上代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int n,t,k,ans,tot;
 8     scanf("%d",&t);
 9     while (t--)
10     {
11         tot=ans=0;
12         scanf("%d",&n);
13         while (n--)
14         {
15             scanf("%d",&k);
16             ans^=k;
17             tot+=k>1;
18         }
19         if (tot)
20         {
21             if (ans) puts("John"); else puts("Brother");
22         }
23         else if (ans) puts("Brother"); else puts("John");
24     }
25     return 0;
26 }

 

posted @ 2013-10-16 22:12  092000  阅读(360)  评论(0编辑  收藏  举报