狗鉴别毒水问题

昨天去蘑菇街面试被虐, 其中智力题更是一点想法也没有, 真是觉得太丢人了...

今天google了一下这道题, 解法有好几种, 仔细思考了一下其实这道题还是很有意思的.

面试官提出的问题大概是这样:

有100瓶水, 其中有1瓶有毒, 有5只狗, 如果狗喝了有毒的水, 则5小时后会毒发身亡. 问如何尽可能快地找出有毒的那一瓶水?

思考

1) 首先, 这里应该有一个隐含的条件, 面试官当时没有直接说, 我猜可能是希望应聘者主动询问的吧: 这里狗尝一瓶水的时间应该是忽略不计的; 由此推论, 狗连续不断地尝若干瓶水的时间也应该是忽略不计的. 这样设定, 后面的分析才比较简洁.

2) 这里的策略有好几种, 但是能否使用却和题目中的这些量的值有关系. 仔细分析这些策略之后就可以明白这一点.

策略一: 二分法

操作:

剩下的若干瓶水均分为两部分(如是奇数不能均分则只能一边多1瓶), 让狗尝其中一部分的所有水, 若此狗5小时后毒发生亡, 则狗尝的这部分水里必然包含了那一瓶毒水. 如此, 将那一部分水再次均分, 重复前面的操作...直到最后就能确定是那一瓶了.

二分法对于程序员来说应该是很容易想到的一种策略(...可是我居然连着都想不起来了TAT). 这的确是一种可行的策略, 但在本题的数量关系下确是不行的: 狗的数量不够. 因为每次尝后, 无法确定狗是死是活, 所以, 为了保证可以完成, 这里至少需要有2^7 = 128只狗(这是很显然的).

策略二: 并行

操作:

因为狗有若干只, 我们完全可以让他们同时工作. 这里有5只狗, 我们可以把总共100瓶水分成5份, 每份20瓶, 每只狗品尝一份中的所有水; 5小时后, 必有一只狗死亡, 则我们就知道那20瓶水中包含着毒水. 然后, 因为剩下4只狗, 我们再把这20瓶水分为4分, 让每只狗品尝1份水......

这个策略和上面的二分法一样, 能否实施也要依赖狗的数量. 显然, 最少需要狗的数量是x! >= 100 的最小整数解. 这里5! = 120 > 100, 显然是足以完成任务的.

从这里我们还可以看到, 这个办法总是会比二分法需要狗的数量少. 这里省略严谨的分析, 我们也可以知道, x!会2^x增长的快些. 当然, 这个办法对狗不是个好消息, 策略一它们还是有活命的希望的, 这里则是必死无疑.

策略三: 二进制编码

策略三对狗的数量的要求和策略一是一致的, 都是求解2^x >= 100 的最小整数解. 然而, 策略三可以仅用5小时(一次观察)就得到答案!

这里x = 7, 所以我们需要7只狗.

操作:

将这100瓶水1~100编号, 显然, 这100个编号均可用7位二进制数表示, 而这7只狗就分别对应一个二进制位. 现在, 看这100个编号的二进制表示, 如果其某个二进制位是1, 则就将这瓶水喂食给对应的狗. 5个小时后, 看一下哪些狗死了, 则它们对应的二进制位就是1, 反之, 没死的就对应0, 这个得到的二进制数字, 就是有毒水的编号.

这个方法的正确性可以这样理解: 对于那瓶有毒的水, 二进制为1的位对应的狗一定会死, 而为0的位对应的狗一定不会死. 这个情况是唯一确定的. 所以, 可以根据狗的死亡的这个情况, 推出毒水的二进制编号.

显然这个方法如果在狗数量足够的情况下是最快且不能再快的.

 

posted @ 2014-03-04 15:05  shenmeyisi  阅读(398)  评论(0编辑  收藏  举报