• 三堆石子


    题目描述:
    有三堆石子,两个人轮流从其中一堆取1到任意颗石子,并约定取走所有三堆中最后一颗石子的人胜利。
    现给定石子数量,问先手有没有必胜策略?
    输入:
    一行,三个正整数a,b,c表示石子数量,用空格隔开。

    输入:
    若先手必胜,输出2个整数x,y,表示先手第一步从第x堆石子取y颗,如果有多种方案致胜,输出所有方案,每行一个,按照取的石子的编号从小到大排序。
    否则输出一行no。

    数据范围:
    分数 数据范围
    10 max(a,b,c)<=10
    30 max(a,b,c)<=50
    30 max(a,b)<=50,c<=10000
    20 max(a,b,c)<=10000
    10 max(a,b,c)<2147483648

    时间限制:1s

    样例数据:
    输入 输出
    2 3 2 1 1
    2 3
    3 1
    1 2 3 no
    3 5 10 3 4
    6 10 12 no
    114514 1919893 1897671 no
    样例解释:
    第1组数据,先手可以取走3颗石子一堆的所有石子。


    题解:本题目是个典型的Nim游戏。用到一个位运算:异或”^”。

                首先一旦从xor为零的状态时取走至少一颗石子,xor就会变得不等于0,再后手取一个相同的数量(为啥见coin game题解),这时xor的值又变成0了!

                 所以必败态一定只能转到必胜态[惊不惊喜,意不意外]所以a1 xor a2 xor a3 xor a4 …… xor an的值如果等于零,则先手必败,因为最后一个石子是后手拿走的。

                如果其值不等于0.则是必胜!好了,现在yes 和 no的问题解决了,再来看yes时的输出方案,如果a>(b^c),a只有在与b xor c相等时,才会a xor b xor c = 0 所以在第一堆当中取走a-(b^c),这时a=a-(a-(b^c))可以得出                  a=b^c。因为第一次取完后,xor的值就等于0了。此时后手就成了“先手”,而xor等于0时“先手”必输,所以后手必输,不就是先手必胜吗!b和c的做法与a相同。得证!

     

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int a,b,c;
    int main()
    {
        freopen("tristone.in","r",stdin);
        freopen("tristone.out","w",stdout);
        cin>>a>>b>>c;
        if((a^b^c)==0) cout<<"no";
        else
        {
            if(a>(b^c)) cout<<"1 "<<a-(b^c)<<endl;
            if(b>(a^c)) cout<<"2 "<<b-(a^c)<<endl;
            if(c>(a^b)) cout<<"3 "<<c-(a^b)<<endl;
        }
        return 0;
    }
  • 相关阅读:
    并发运行的思维模型
    进程和线程的区别
    拿来主义
    同步组件合作和团队合作 让世界变得更美好
    strace a++;b++;a+b;
    System 88: GDB Overview
    numpy多维数组维度及添加轴的理解
    Numpy入门
    python列表list 和numpy.array区别
    数组的生成方法
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11149998.html
Copyright © 2020-2023  润新知