Nim
题目链接: http://poj.org/problem?id=2975
题意:
给你N堆石头,让你和另一个人进行Nim博弈,每个人可以拿任意一堆中不少于一的石子,当谁无法石子拿时将失败。问你先手必胜有几种拿法。
思路:
参考一位大神的想法
Nim博弈的本质是始终维持各个堆的异或为零的状态,这样我们只许对每一堆进行判断,判断先拿这一堆能否维持异或为零
那么我们需要将除了这一堆以外的所有异或算出来,看自己是否严格大于他,大于他才能够将自己减小到这个值。
备注:异或的优先级非常低,比 > 还低。
代码:
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cstdio>
#include <string>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <sstream>
#include <memory>
#include <iostream>
#include <algorithm>
using namespace std;
#define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++)
#define debug(x) cerr<<#x<<":"<<x<<endl
#define pb push_back
typedef long long ll;
const int MAXN = (int)1e6+7;
int A[MAXN];
int main()
{
int N;
while (scanf("%d",&N),N) {
int t = 0;
rep(i,1,N) {
scanf("%d",&A[i]);
t ^= A[i];
}
int ans = 0 ;
rep(i,1,N) {
if (A[i] > (t^A[i])) {
ans ++;
}
}
if (t == 0) {
puts("0");
continue;
}
printf("%d\n",ans);
}
}