题解 P4279 【[SHOI2008]小约翰的游戏】

VenusM1nT

2020-10-27 22:15:43

Solution

这是一道经典的 $\textbf{Anti - Nim}$ 问题。 ![](https://t1.picb.cc/uploads/2020/10/26/tYOSar.png) 先说结论:当每堆石子都只有 $1$ 个的时候分奇偶讨论,否则求异或和,若异或和 $>0$ 则先手必胜。 再来尝试口胡一下正确性。 ![](https://t1.picb.cc/uploads/2020/10/26/tYMvgD.png) 定义“孤单堆”为只有一颗石子的堆,“充裕堆”为石子数 $>1$ 的堆,下面定义若干状态:$\text{S/T}$ 分别代表异或和 $\not=0$ 与 $=0$ 的状态,$\text{S}/0/1/2$ 代表在 $\text{S}$ 状态下充裕堆的数量 $=0/=1/\ge2$,$\text{T}/0/2$ 代表在 $\text{T}$ 状态下充裕堆的数量 $=0/\ge2$,没有 $\text{T}1$ 是因为如果充裕堆的数量 $=1$ 则异或和不可能为 $0$。下有若干推论。 - 显然 $\text{S}0$ 时必败,$\text{T}0$ 时必胜,因为此时是若干孤单堆,$\text{S/T}$ 分别代表奇偶状态。 - **$\text{S}1$ 时先手必胜。** 若孤单堆为奇数则取走整堆,否则取成孤单堆。 - $\text{S}2\to\text{T}0$ 为非法,因为不能同时取两堆,但 $\text{S}2\to\text{T}2$ 是合法的。 - $\text{T}2\to\text{S}0$ 为非法,原因同上,但 $\text{T}2\to\text{S}2/1$ 为合法。 - $\text{S}2$ 时先手必胜。先手直接 $\text{S}2\to\text{T}2$,此时若后手 $\text{T}2\to\text{S}2$ 则重复上面的操作,最终后手必然 $\text{T}2\to\text{S}1$,此时先手必胜。 最终得出结论:$\text{T0,S1,S2}$ 时先手必胜,$\text{S0,T2}$ 时先手必败,也就是最上面的结论。 大概就是这个亚子。 ![](https://t1.picb.cc/uploads/2020/10/26/tY8kz8.png) ```cpp #include<bits/stdc++.h> #define N 50 #define reg register #define inl inline using namespace std; int n,a[N+5]; int main() { reg int Time; scanf("%d",&Time); while(Time--) { reg int ans=0; reg bool fg=1; scanf("%d",&n); for(reg int i=1;i<=n;i++) { reg int x; scanf("%d",&x); ans^=x; fg&=(x==1); } if(fg) puts(ans?"Brother":"John"); else puts(ans?"John":"Brother"); } return 0; } ```