吃糖果的游戏

题目描述

吃糖果的游戏
  桌子上放着两堆糖果,Matrix67和Shadow轮流对这些糖果进行操作。在每一次操作中,操作者需要吃掉其中一堆糖果,并且把另一堆糖果分成两堆(可以不相等)留给对方操作。 游戏如此进行下去,糖果数会越来越少,最后必将出现这样 一种情况:某人吃掉一堆糖果后发现另一堆里只剩一块糖果 不能再分了。游戏规定此时该操作者吃掉最后这一块糖果从 而取胜。
  这个游戏是不公平的。对于任意一种初始状态,总有一方有必胜策略。所谓有必胜策略是指,无论对方如何操作,自 己总有办法取胜。
  Matrix67和Shadow将进行10次游戏,每一次游戏中总是Matrix67先进行操作。Matrix67想知道每一次游戏中谁有必胜策略。

输入数据

  输入数据一共 10 行,每行有两个用空格隔开的正整数,表示一次游戏开始时桌子上两堆糖果分别有多少个。
  对于 50 的数据,这些正整数均不超过100;
  对于 70 的数据,这些正整数均不超过 10 000 ;
  对于100%的数据,这些正整数均不超过 10 000 位。

输出数据

  输出十行字符串。这些字符串只能是“Matrix67”或“Shadow”,它们表示对应的十行输入数据中有必胜策略的一方。
  请注意大小写。

样例输入
1 1
1 2
1 3
1 4
1 5
2 1
2 2
2 3
2 4
2 5
样例输出
Matrix67
Matrix67
Matrix67
Matrix67
Matrix67
Matrix67
Shadow
Shadow
Matrix67
Matrix67

问题分析

  假设现在轮到你吃,摆在你面前的是糖果堆A和B。当你吃完堆A后,B将决定你的命运:

  • B = 1: (自己获胜)
  • B = 2:2=1+1,将有一份是1,自己将失败
  • B = 3:3=1+2,将有一份是1,自己将失败
  • B = 4: (自己必胜)
      4 = 1+3,在必胜策略下,自己不会这样划分糖果
      4 = 2+2,你该感到庆幸,你把烫手的山芋扔给了对方,对方无论吃掉哪一堆糖果,对另一堆糖果划分的时候总是有1
  • B=5: (自己必胜)
     5=1+4,在必胜策略下,自己不会这样划分糖果
     5=2+3,你该感到庆幸,你把烫手的山芋扔给了对方
  • B=6: (自己必胜)
     6=1+5,在必胜策略下,自己不会这样划分糖果
     6=2+4,在必胜策略下,自己不会这样划分糖果。因为对方将2吃掉,剩下的4划分为2+2,那么自己将必败
     6 = 3 + 3,总能立于不败之地,把烫手的山芋扔给了对方,此时,自己将必胜
  • B = 7: (自己失败)
    自己将在劫难逃!因为7 = 1 + 6 = 2 + 5 = 3 + 4。
     7 = 1 + 6,将有一份是1,自己将失败
     7 = 2 + 5,可以勉强坚持一轮,但对方吃掉2,把剩下的5分成2和3送给你,自己就输定了;
     7 = 3 + 4,对方吃掉3,把剩下的4分成2和2,自己就输定了;
  • B=8: (自己必败)
      B=1 + 7,将有一份是1,自己将失败
      B=2 + 6,对方吃掉2,对方把剩下的6分成3+3,自己吃掉3,剩下的3将分出一个1,自己输。
      B=3 + 5 ,对方吃掉3,对方把剩下的5分成2+3,自己不管吃掉2还是3,剩下的都将分出一个1,自己输。
      B=4 + 4 ,对方吃掉4,对方把剩下的4分成2+2,自己吃掉2,剩下的2将分出一个1,自己输。
  • B = 9: (自己获胜)
      9 = 2 + 7,无论对方吃掉哪一个都,剩下的一个都不好分,对方将输;
  • B = 10: (自己获胜)
      10 = 3 + 7,无论对方吃掉哪一个都,剩下的一个都不好分,对方将输;
      10 = 2 + 8,无论对方吃掉哪一个都,剩下的一个都不好分,对方将输;
1. B = [2, 3, 7, 8] 自己输,对方赢;
2. B = [1, 4, 5, 6, 9, 10] 自己必赢。

对于大于10的情况,我们可以设a = [2, 3, 7, 8],b = [1, 4, 5, 6, 9, 10]。

观察集合a和b,我们可以发现每个b元素都能写成两个a元素之和对10求余的形式:
1 = (3 + 8) % 10; 4 = (2 + 2) % 10; 5 = (2 + 3) % 10; 6 = (3 + 3) % 10; 9 = (2 + 7) % 10; 10 = (3 + 7) % 10;

考虑两堆都大于10的情况1
(1) 10i+a,10i+a。则67必输。
  不管你吃掉哪一堆,留下的第二个数都是10 * i + a,这时你无论怎么分,分出来的两个数中肯定有一个可写为10 * i + b的形式,而10 * i + b = 10 * j + a + 10 * k + a,即两个数的个位数字都是集合a中的数,这样经过一轮后,回到你手里的还是两个10 * i + a,你没办法赢。
(2) 10i+a,10i+b,你可以吃掉10i+a,然后把10i+b分成两堆10i+a,67必胜。
  你把堆10 * i + a 吃掉,剩下的堆10 * j + b分成两个10 * i + a,稳操胜券。
(3) 10
i+b,10*i+b。67必胜。
  摆在你面前的两个堆的数量都可写为10 * i + b的形式,这样不管你吃掉那一堆,都可以把剩下的一堆分成10 * i + b = 10 * j + a + 10 * k + a,这样送给对方的是两个10 * i + a,他输定了。
如果两个堆数量的个位数字都属于集合a,先拿者Matrix67必败,否则Matrix67胜。

if __name__ == '__main__':
    yushu = [2, 3, 7, 8]
    for i in range(10):
        a, b = list(map(int, input().split()))
        yushu_a, yushu_b = a % 10, b % 10
        if yushu_a in yushu and yushu_b in yushu:
            print("Shadow")
        else:
            print("Matrix67")

  1. https://blog.csdn.net/goal00001111/article/details/3555958 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还能坚持

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值