• 51nod【1069 Nim游戏】


    有N堆石子。A B两个人轮流拿,A先拿。每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N及每堆石子的数量,问最后谁能赢得比赛。
    例如:3堆石子,每堆1颗。A拿1颗,B拿1颗,此时还剩1堆,所以A可以拿到最后1颗石子。
    Input
    第1行:一个数N,表示有N堆石子。(1 <= N <= 1000)
    第2 - N + 1行:N堆石子的数量。(1 <= A[i] <= 10^9)
    Output
    如果A获胜输出A,如果B获胜输出B。
    Input示例
    3
    1
    1
    1
    Output示例
    A


    尼姆博奕(Nimm Game):有三堆各若干个物品,两个人轮流从某一堆取任意多的
    物品,规定每次至少取一个,多者不限,最后取光者得胜。

        这种情况最有意思,它与二进制有密切关系,我们用(a,b,c)表示某种局势,首
    先(0,0,0)显然是奇异局势,无论谁面对奇异局势,都必然失败。第二种奇异局势是
    (0,n,n),只要与对手拿走一样多的物品,最后都将导致(0,0,0)。仔细分析一
    下,(1,2,3)也是奇异局势,无论对手如何拿,接下来都可以变为(0,n,n)的情
    形。

        计算机算法里面有一种叫做按位模2加,也叫做异或的运算,我们用符号(+)表示
    这种运算。这种运算和一般加法不同的一点是1+1=0。先看(1,2,3)的按位模2加的结
    果:

    1 =二进制01
    2 =二进制10
    3 =二进制11 (+)
    ———————
    0 =二进制00 (注意不进位)

        对于奇异局势(0,n,n)也一样,结果也是0。

        任何奇异局势(a,b,c)都有a(+)b(+)c =0。

    如果我们面对的是一个非奇异局势(a,b,c),要如何变为奇异局势呢?假设 a < b
    < c,我们只要将 c 变为 a(+)b,即可,因为有如下的运算结果: a(+)b(+)(a(+)
    b)=(a(+)a)(+)(b(+)b)=0(+)0=0。要将c 变为a(+)b,只要从 c中减去 c-(
    a(+)b)即可。

        例1。(14,21,39),14(+)21=27,39-27=12,所以从39中拿走12个物体即可达
    到奇异局势(14,21,27)。

        例2。(55,81,121),55(+)81=102,121-102=19,所以从121中拿走19个物品
    就形成了奇异局势(55,81,102)。

        例3。(29,45,58),29(+)45=48,58-48=10,从58中拿走10个,变为(29,4
    5,48)。

    题解:
    #include <iostream>
    using namespace std;
    int main()
    {
        int n,x;
        cin>>n;
        int ans=0;
        while(n--){
            cin>>x;
            ans^=x;
        }
        if(ans!=0) cout<<"A"<<endl;
        else cout<<"B"<<endl;
        return 0;
    }
    

  • 相关阅读:
    sort详解
    php之opcodes
    [转载] PHP升级导致系统负载过高问题分析
    Openresty实现获取内部location
    LUA语法汇总
    Openresty常用指令和参数
    PHP中的垃圾回收机制
    MySQL字段类型VARCHAR
    笔试题多线程
    笔试代码考查
  • 原文地址:https://www.cnblogs.com/kzbin/p/9205199.html
Copyright © 2020-2023  润新知