poj2975 Nim 博弈

      自从省赛结束了,好久都做过博弈题了,感觉都快忘了。今天找了几题练练手,在做过程中,感觉这道题挺有意思的。题目的意思是说,在Nim游戏中,先手有几种方式让 Nim 和变为0。(不知道Nim游戏的,请参考: 这里
       其实我觉得这道题就是披着博弈的外衣,然后来考查你异或运算符(^)的使用的。在做题之前,我们想要了解异或运算符(^)的一个重要的性质:
       现在我们有三个整数a, b, c: 
       我们假设c = a ^ b, 那么我们可以得到 b = c ^ a, a = b ^ c(交换律对异或运算符是成立的)。
       现在我们在来分析一下这道问题,假设sum 为 Nim和,a为某一堆的个数,b为其余堆的Nim和。那么我们就可以得到 sum = a ^ b。我们的任务是让sum变为零,所以我们只要让 a 等于 b,就可以达到我们的目的了。有上述的性质,我们可以将式子边形为b = sum^a。
因为b我们不好改变,所以我们只能从a下手。换而言之,我们只需让a变为b就可以达到目的。所以题目就变成了,存在多少个能够变为b的a。也就是说,有多少个a大于b(因为题目说石子只能减少)。
      现在问题就变得十分容易了,从这一题我们可以得到一个结论。简化问题的能力是至关重要的,在解题过程中重点就是要培养这种能力。
【代码如下】
#include <stdio.h>
#define MAXN 1000 + 10
int main(){
    int n, Nim[MAXN], ans, cnt, i;
    while(scanf("%d",&n),n){
        for(i = ans = 0; i < n; i++){
            scanf("%d", &Nim[i]);
            ans ^= Nim[i];
        }
        for(i = cnt = 0; i < n; i++){
            if((ans^Nim[i]) < Nim[i]) cnt++;
        }
        printf("%d\n", cnt);
    }
    return 0;
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值