POJ 3480 John
[★★★☆☆]博弈论 Nim游戏
题目大意:
有若干堆石子,两个人轮流从其中一堆里面取出若干个(不能不取),若某个人取完后没有石子了,则这个人输。先手的人叫John。
输入格式:
T(T组样例)
N(N堆石子)
Ai(每堆石子的个数)输出格式:
John胜输出 “John”,否则输出 “Brother”。
样例
输入:
2
3
3 5 1
1
1
输出:
John
Brother解题思路:
Nim游戏的变体,有稍微有一点难度。
首先一眼看出来是Nim游戏,只是获胜条件相反,我们就来用XOR来思考。
1.因为都想避开1,所以先考虑所有堆的个数都是1的情况。显然,偶数个堆先手胜,否则必败。
2.存在1个个数不是1的堆,根据剩下的堆奇偶性选择全取或者剩下一个转换为情况1,先手必胜。
3.存在多个个数不是1的堆,我们开始考虑XOR值。若XOR值不为0,先手的人可以使局面转化为2,先手必胜。否则必败。代码
#include <iostream>
using namespace std;
const int MAXN = 10000;
int A[MAXN];
int main() {
int T;
int n;
cin >> T;
while (T--) {
bool all1 = 1;
int x = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> A[i];
if (A[i] != 1) all1 = 0;
}
for (int i = 0; i < n; i++) {
x ^= A[i];
}
if ((x == 0 && all1 == 0) || (all1 == 1 && x != 0)) puts("Brother");
else puts("John");
}
}