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 }
如有转载,请注明出处(http://www.cnblogs.com/lochan)