思路:可以对任意一堆牌进行操作,根据Nim博弈定理--所有堆的数量异或值为0就是P态,否则为N态,那么直接对某堆牌操作能让所有牌异或值为0即可,首先求得所有牌堆的异或值,然后枚举每一堆,用已经得到的异或值再对这堆牌异或,就能得到其他牌堆的异或值,如果当前牌堆的数量大于该异或值,就说明可以拿走一些牌让当前堆牌数等于异或值,两者异或为0,则对手处于P态。
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 = 100 + 5; int a[maxn]; int main() { int n; while(scanf("%d", &n) == 1 && n) { int res = 0, cnt = 0; for(int i = 0; i < n; ++i) { scanf("%d", &a[i]); res ^= a[i]; } if(!res) { //已经输了 printf("0\n"); continue; } for(int i = 0; i < n; ++i) { int x = res ^ a[i]; if(x < a[i]) cnt++; } printf("%d\n", cnt); } return 0; }
如有不当之处欢迎指出!