m 堆石子,每堆 n[i] 個。兩人輪流從任意一堆取走任意多(≥1)石子,取走最後一顆者勝。給定初始狀態,判斷先手勝負。
先手必勝 ⇔ 所有堆石子數異或和 ≠ 0。
異或和 X = n[1] ⊕ n[2] ⊕ ... ⊕ n[m]。
- X = 0:當前為 P-position(先手必敗,對手有完美策略)。
- X ≠ 0:當前為 N-position(先手有必勝策略)。
若 X ≠ 0,找到最高位為 1 的二進制位 k。必存在某堆 n[i] 第 k 位為 1。將該堆改為 n[i] ⊕ X(嚴格小於 n[i]),則新異或和歸零,轉為 P-position。
#include <cstdio>
using namespace std;
int main() {
int m;
while (scanf("%d", &m) == 1 && m) {
int x = 0, val;
for (int i = 0; i < m; ++i) {
scanf("%d", &val);
x ^= val;
}
puts(x ? "Yes" : "No"); // 題目輸出格式:先手勝輸出 Yes
}
return 0;
}