题目:
分析:所有堆的异或为0时,先手必败;某个堆取出多少个石子时可以让所有堆的石子数异或值为0
让异或为0的方法:遍历每一堆,对于遍历到的某一个堆a[i],从a[i]中拿走每个堆的异或all^a[i]
那么a[i]剩下的就是(a[i]-all异或a[i]),最后得到all=all异或(a[i]-all^a[i])=0。
显然,如果最开始所有堆的异或不为0,那么就可以从某一堆中取一些石头,让所有堆异或为0,那么被拿石头的那一堆就得满足a[i]>all异或a[i]才能从a[i]中拿走all^a[i]个石头。
#include<cstdio>
#include<algorithm>
#include<cmath>
#pragma warning(disable:4996)
using namespace std;
const int MAXN = 1e6 + 9;
int T, n, m, y, d, a[MAXN];
int main() {
while (scanf("%d", &n) != EOF && n != 0) {
int all = 0, count = 0;
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
all = all ^ a[i];
}
if (all == 0)printf("0\n");
else {
for (int i = 0; i < n; i++) {
if (a[i] > (all ^ a[i]))count++;
}
printf("%d\n", count);
}
}
return 0;
}