很明显,编程并不是这一道题目的重点,重点是题目背后的知识——威佐夫博弈。其实这就是编程的魅力,有的时候代码本身并不难,难点还是在于代码背后的逻辑,还是在于人,只要你的大脑知道怎么做,那么代码肯定能写出来,所以说啊,写代码看似是在写ABCD,其实是在写你大脑中的逻辑!

    什么是威佐夫博弈呢,其实这道题目本身就已经是很好的描述了,我们简单来分析一下:

    第一个(0,0),肯定是先手输,为啥?因为当先手兴冲冲地上来准备拿第一手时,发现已经是(0,0)了,他没石子可拿了,那最后的石子去哪了?肯定在上一局被它对手取光了,所以先手只能认输,而对手稳赢,因为规则就是第一个把石头取光的赢得胜利。

    第二个(1,2),也是先手必输,为啥?因为先手上来取第一手时他只有四种取法:

        1):在1中取1个,那么后手就把2中剩余的2个全部取光:先手输,后手赢

        2):在2中取1个,那么后手在两堆中各取1个,石头又光了,先手又输了

        3):在2中取两个,后手取1中剩下的一个,石头又光了,先手又输了

        4):两堆中各取1个,后手取走2中剩余的1个,石头又光了,先手又输了

    综上所述,对于(1,2)这种情况,无论先手怎么取,都是死路一条,必输!

    第三个(3,5),先手还是死路一条,无论先手怎么取,最后兜兜转转都回到情形(1,2),上面已经分析过了,(1,2)先手必死无疑,可怜的先手啊!

    第四个 ( 6 ,10  )

    第五个 ( 8 ,13)

    第六个 ( 9 , 15)

    第七个 ( 11 ,18)……这些情况先手毫无招架能力,只能认输,那么这些数字到底有什么规律?规律有两个:
    一是从(0,0)开始到(11,18),两个数之间的差值是递增的分别是0,1,2,3,4,5,6,7……

    二是每一局中的第一个值是前面所有的局中没有出现的数字,比如第三个局面,前面出现了 0  1 2,那么第三个局面的第一个值为 3 ,比如第五个局面,前

面出现了 0  1  2 3 4 5 ,那么第五个局面第一个值为6。

    还有一个规律就是:第一个值 = 差值*1.618,这个才是解决此题的关键,而1.618 = (sqrt(5)+ 1) /  2 ,所以当我们拿着任意一组的两个值,只要判断一下是否符合“ 第一个值 = 差值*1.618”即可,如果是,那就是先手必输,不是,先手必赢!好了,看代码:

#include#include#include int main() {
    int a = 0, b = 0;
    while (~scanf("%d %d", &a, &b)) {
        //先把二者之中的较小值放在左侧
        if (a > b) {
            int temp = a;
            a = b;
            b = temp;
        }
        if (a == b) {//包括0 0这种特殊情况
            printf("1\n");//先手必胜
        } else if (a == (int)((b-a)*((sqrt(5)+1)/2))){
            printf("0\n");//先手必输
        } else {
            printf("1\n");//先手必赢
        }
    }
    return 0;
}


点赞(0)
 

0.0分

10 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 10 条评论

axiba删不掉 3年前 回复TA
。。
axiba删不掉 3年前 回复TA
axiba删不掉 3年前 回复TA
超管有吗
axiba删不掉 3年前 回复TA
axiba删不掉 3年前 回复TA
删又删不掉,tmd烦死了
axiba删不掉 3年前 回复TA
完了,社死
axiba删不掉 3年前 回复TA
我去,这评论删不了吗
axiba删不掉 3年前 回复TA
说错了。。怎么删评论
axiba删不掉 3年前 回复TA
说错了,是(2,4)这种,(4-2)*1.618取整等于2
axiba删不掉 3年前 回复TA
我对你的答案提出疑问。
你在判断时只判断了两堆数的比例,然而实际上这些先手必输的情况中并不是连续的,小的数为a大的数为b时,比如a=1对应b=2,a=3对应b等于5,但是a=2时没有b与之对应。
而按照你的说法(2,3)这组数也会被判定为必输,因为(3-2)*1.618取整等于2符合你的判断。但是实际上在(2,3)这种情况下你只需要把3个那一堆拿走2个,就会变成(2,1),对方必输,你其实是必赢。