POJ 2975 Nim

版权声明:本文是博主乱写的文章,可以随便转载 https://blog.csdn.net/weixin_43768644/article/details/89301473

题目链接https://vjudge.net/problem/POJ-2975

题解

1.令n堆异或和为   sum,如果sum=0,当前必败,也就没有必胜的方法

如果sum不等于0,每次判断一个堆是否有可取方法使得 当前堆去掉几个后 异或 剩余n-1个堆的sum值 =0

栗子:假设剩下堆的sum值为0101,那么如果当前堆大于等于0101,那么一定可以拿走几个使得当前为0101,然后总sum变为0

于是当时我的代码判断部分是这样的:(不用  <= ,如果a[i]^sum==a[i] 表明原来sum是0 ,必输,之前特判掉了

int cnt=0;
if (!sum) { printf("0\n");continue;}
for (int i=0;i<n;i++) if (a[i]^sum < a[i]) cnt++;

结果输入

3

7 11 13

这组数据的答案是0,神奇的一比

这是运算符优先级的问题,所以记得加个括号。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;

ll a[1010];

int main()
{
    int n;
    while (~scanf("%d",&n),n){
        ll ans = 0;
        for (int i=0;i<n;i++){
            scanf("%lld",a+i);
            ans ^= a[i];
        }
        if (!ans) {printf("0\n");continue;}
        ll cnt = 0;
        for (int i=0;i<n;i++) {
            //printf("ans^a[i]=%lld a[i]=%lld\n",ans^a[i],a[i]);
            if( (ans^a[i]) <= a[i]) cnt++;
        }
        printf("%lld\n",cnt);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43768644/article/details/89301473