HOJ 1367 A Stone Game(anti-nim)

题目链接http://acm.hit.edu.cn/problemset/1367

解题思路:这个nim游戏是谁取最后一份谁输.(0堆的时候相当于上一个人取完了最后一堆,先手必胜)

假设n堆异或和为nim

有以下状态:

①:每堆为1

--->nim=0,偶数堆     nim!=0,奇数堆   对应:

     先手必胜                先手必败

②:有一堆大于1个,其余为1个

--->由堆数奇偶判断大于1个的那堆剩一个还是取完

先手必胜

③:至少有两堆大于1个:

(1)nim=0,取一次后转化为②或者③(2)

(2)nim!=0,必定可以转化为nim=0且至少有两堆大于1,也就是转化为③(1)


          nim可以变为0是显然的,那么为什么剩下至少有两堆大于1呢?

         举个例子:nim和二进制下   1xxxxx,那么我们知道这个最高位是其中一个大于一的堆x,现在先移除a[x],剩余n-1项            nim    =     nim^a[x]。

         那么这个二进制数就变成了0yyyyy,当剩余还有两堆大于1的石堆时,显然成立,如果只有一堆,我们可以保证

         0yyyyy中间四位存在一个1,就是剩下那堆大于2的造成的,那么移除的那一堆需要取走几个后剩下的石子数需要 xor nim

         =0,那么很显然 这个被移除的堆剩下放回来的必须大于1.


分析:当初始状态为③(2),一定会在不停地取中使得自己变为②,所以③(2)状态先手必胜

           当初始状态为③(1),一定会不停地取使得对方变为②,先手必败

总结:

先手必胜两种情况:

①nim=0,全是1

②nim!=0,有大于1的

代码:

#include<cstdio>
#include<cstring>
int main()
{
    int n;
    while (~scanf("%d",&n)){
        int ans=0,x,morethan1=0;
        for (int i=0;i<n;i++){
            scanf("%d",&x);
            ans ^= x;
            if (x>1) morethan1 = 1;
        }
        if ((ans==0 && morethan1==0)||(ans>0 && morethan1==1)) printf("Louis\n");
        else printf("Lester\n");
    }
    return 0;
}

博弈论暂时告一段落,学线段树去啦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值