[BZOJ1022][SHOI2008]小约翰的游戏
sol
显然这个玩意儿和普通\(Nim\)游戏是有区别的。
形式化的,\(Nim\)游戏的关键在于决策集合为空者负,而这里的决策集合为空者胜。
所以就显然不能直接用\(SG\)函数的那套理论。
这种“决策集合为空者胜”的博弈游戏被称为\(Anti-SG\)游戏。
有一个\(SJ\)定理是这样的:
对于一个\(Anti-SG\)游戏,如果我们规定当局面中所有的单一游戏的\(SG\)值为\(0\)时游戏结束,则先手必胜当且仅当满足下列条件之一:
游戏的\(SG\)值不为零且游戏中某个单一游戏的\(SG\)值大于一。
游戏的\(SG\)值为零且游戏中不存在某个单一游戏的\(SG\)值大于一。
放到这题中,因为石子可以被任意数量拿取,所以\(SG\)值就等于石子数量。根据\(SJ\)定理,小约翰必胜的条件就是:
所有石子异或和不为零且存在一堆石子个数大于一;
所有石子异或和为零且不存在某一堆石子个数大于一。
code
#include<cstdio>
#include<algorithm>
using namespace std;
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
int main()
{
int T=gi();
while (T--)
{
int n=gi(),Max=0,Sum=0;
for (int i=1,x;i<=n;++i)
x=gi(),Max=max(Max,x),Sum^=x;
puts((Sum&&Max>1)||(!Sum&&Max<=1)?"John":"Brother");
}
return 0;
}