先手必胜的条件:
1. 每一个小游戏都只剩一个石子了,且SG = 0.
2. 至少有一堆石子数大于1,且SG不等于0
证明:1. 你和对手都只有一种选择,随便怎么拿,你都赢了
2. a:如果只有一堆石子数量大于1,那么你赢了,你可以拿完使得整个游戏的1的数量不变,剩余1个整个游戏1的数量增加。
b:如果至少有两堆石子数大于1,那么你可以让SG变为0,令对手处于P态,并且当前至少有两堆数量大于1,对手无论怎么拿SG都会变成非0.
结论:当石子数量全为1时,且SG=1必输,当石子数有大于两堆的石子数量大于2,且SG!=0,必输,其他情况都是必赢。
AC代码
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 1e4 + 5;
void in(int &a) {
char ch;
while((ch=getchar()) < '0' || ch >'9');
for(a = 0; ch >= '0' && ch <= '9'; ch = getchar()) {
a = a * 10 + ch - '0';
}
}
int main() {
int T, n;
scanf("%d", &T);
while(T--) {
in(n);
int res = 0, x, cnt = 0;
for(int i = 0; i < n; ++i) {
in(x);
res ^= x;
if(x > 1) ++cnt;
}
if(cnt == 0 && res || !res && cnt >= 2) printf("Brother\n");
else printf("John\n");
}
return 0;
}
如有不当之处欢迎指出!