zoukankan      html  css  js  c++  java
  • 经典逻辑题 百人戴帽子问题

    题目: 有100个人商量做一个游戏,在游戏开始之前他们商定一个策略,然后每人戴一顶帽子,帽子上是1~100的随机数,游戏开始后每人只能看到其他人头上的帽子的数字。这时要求所有人同时说出一个数字来猜自己头上的帽子,问是否存在一个策略(策略比赛开始之前商定)使得:至少有一个人说出的是自己头上的数字?

     

    这个问题曾经纠结本人数天,苦思不得求解。该题目存在简单版本的提示:即就是2个人的情况下是怎么样商定策略的。

    提示一:


    当题目简化成只有2个人的时候,可以知道头上帽子的数字不是0就是1。

    可以将所有的情况穷举出来

    帽子一     帽子二

    0            0

    0            1

    1            0

    1            1

    上述的情况可以划分成两类:

    类别1:

    0            0

    1            1

    类别2:

    0            1

    1            0

    上述两个类别中,类别1的两人只要商定策略 "我们都报对方头上的数字" 就都可以答对,相反,如果商定策略 "我们都报对方头上相反的数字" 那就全部打错。

    类别2中的两人只要商定策略 "我们都报对方头上相反的数字" 就可以全部答对, 反之,则全部答错。

    根据类别1和类别2可以中和一下策略: "你报我头上的数字, 我报你头上相反的数字"。则可以得到如下结果:

    帽子一     帽子二    戴帽子一的人报的数字  戴帽子二的人报的数字

    0            0            0                             1     

    0            1            1                             1

    1            0            0                             0

    1            1            1                             0

    这种商定策略可以保证 至少有一个人且仅有一个人答对数字

    根据上述简化版的分类方式,百度上有个投机取巧的方法可以求解该题目:

    解答一:


    百度知道中有人回答: 

    从100个人中随机抽一个人(A)出来,叫他(A)把相同数字的人围成圈站一起。Ⅰ有圈的情况下,让他(A)对大家说:“报出各自圈子里看到的数字,没站成圈的随便报,A自己也随便报。”Ⅱ没圈的情况下,A进去,让A换个人(B)出来做指挥,让他(B)把相同数字的人围成圈站一起。 ①若无圈,叫A让B对大家说:“报出自己没看到的数字。” ②若有圈,叫A让B对大家说:“报出各自圈子里看到的数字,没站成圈的随便报,B自己随便报。”请大家看看这样接合乎逻辑不,有没有犯规。

    这种方法如果存在圈那就一定有人答对,因为圈内的人数字都相同。如果不存在圈,则所有数字不重复,那除去自己看到的数字就只剩自己头上帽子的数字了。但是,这种方法本身需要有个人(A)出来管制策略,从创新的角度来说,是个相当简单便捷的方法,但是如果规则硬性规定不能有个人出来管制策略呢?

    解答二:


    回归到原来的提示一,在提示一的基础上就没有办法将问题扩展回原来的100人,甚至是1000人以及1000个数字的情况嘛?

    我们来寻找下类别1和类别2的共同规律,可以发现类别2两个帽子的总数相加的总数是固定值1,类别1的帽子的总数也同样是固定值,分别是0和2。

    既然帽子的总数是固定值,那我们可以不可以通过猜总数值来猜自己头上的数字呢?但是0、1两个数字的总数值可以是0、1、2三种结果,而人数却只有2个,只能猜测两种结果。

    其实这里仔细考虑下可以发现实际上0、1连个总数的值并没有3种结果,当有一个数字的值是1时,那么结果只可能是1、2两种。为了方便运算起见,我们将结果值对人数取余,则0、1、2取余的结果是0、1两个结果。

    那么只要一开始的时候规定好自己将要猜的结果余数值,就可以将所有可能的结果情况列举一遍,这样就其中一个人就可以将唯一答案给说中,如此就确保有且仅有一个人猜对自己头上的数字。

    首先以2个人为例子 A猜结果余数为0的值, B猜结果余数为1的值

    A  B      A的计算过程             B的计算过程               A的结果       B的结果

    0  0      (A + 0) % 2 = 0       (B + 0) % 2 = 1        0               1

    0  1      (A + 1) % 2 = 0       (B + 0) % 2 = 1        1               1

    1  0      (A + 0) % 2 = 0       (B + 1) % 2 = 1        0               0

    1  1      (A + 1) % 2 = 0       (B + 1) % 2 = 1        1               0

    通过上述例子,我们可以发现和提示一所产生的答案完全一致,但是利用该方法可以引伸到更多的人数设置是100人、1000人以及更多。

    我们再以 3个人为例子进行一次校验, A商定余数结果是0、B是1、C是2

    A  B  C      A的计算过程             B的计算过程           B的计算过程               A的结果       B的结果    C的结果

    0  1  0      (A + 1) % 3 = 0       (B + 0) % 3 = 1     (C + 1) % 3 = 2        1               1            1

    0  1  2      (A + 3) % 3 = 0       (B + 2) % 3 = 1     (C + 1) % 3 = 2        0               2            1

    2  2  1      (A + 3) % 3 = 0       (B + 3) % 3 = 1     (C + 4) % 3 = 2        0               1            1

    ... 

    因为ABC总共有3的3次方27种情况,就不一一列举了。

    即一开始商定策略:

    (自己要报出来的数字 + 看的所有数字的总和) % 总人数 = 自己预定义的结果余数编号

    解答补充:


    上述解答是经同学指导得到,但是并不一定是唯一解,希望大家能够给出更加简便或者特殊的解答方法,共同交流。解答补充希望有大牛帮忙指导!

  • 相关阅读:
    Nginx介绍
    linux vi编辑
    MySql数据类型
    Mysql用户权限控制(5.7以上版本)
    Linux上安装MySQL
    Java得到指定日期的时间
    Spring Boot 整合Redis 实现缓存
    编写高效优雅Java程序
    JVM调优和深入了解性能优化
    JVM执行子程序
  • 原文地址:https://www.cnblogs.com/chenxing/p/2637497.html
Copyright © 2011-2022 走看看