有看到一个程序员的面试题,觉得很有趣,这里贴出来分享:
试验室有16 瓶水,其中一瓶是有毒的,使用若干只青蛙实验,青蛙喝了有毒的水后会在1小时后死亡,只有1个小时,请问:
1.如何使用最少的青蛙测出哪瓶水有毒?
2.需要几只青蛙?
解答:
本道题的目的有两个,一个是找出有毒的水是哪一瓶,另一个是计算需要使用的青蛙数量
1. 最笨的方法,使用16只青蛙,每只对应一瓶水,这样,哪只青蛙死了,那瓶水就是有毒的水。但是这样的话,我们就需要使用16只青蛙,有点浪费了。不过在很无奈的情况下,这是很有效的方法。但是显然这不是我们需要的答案
2.使用数学中的二分法:
第一次试验:将水分成两份,每份取样8瓶水的样品,这样就有两份样品,使用一只青蛙喝其中份样品的水,如果青蛙死掉了,则毒水在本份样品中,则再次将样品对应的水分成两份;如果青蛙没有死,则毒水在另一份样品对应的水中,则将另一份样品对应的水平均分成两份
第二次试验:对第一次试验结果的水分成两份,每份取样4瓶。这样按照第一次试验的方式,找出毒水所在的范围,即找出毒水在哪个4瓶样品中
第三次试验:对第二次试验结果的水分成两份,每份取样2瓶。这样按照第一次试验的方式,找出毒水所在的范围,即找出毒水在哪个2瓶样品中
第四次试验:对第三次试验结果的水分成两份,每份取样1瓶,这样按照第一次试验的方式,找出毒水在哪一个样品中
答案:需要4只青蛙,就能确定哪瓶水有毒
OK,完美 收工
但是----------,请不要忘记了,只有一个小时的试验时间,我们这样使用二分法的话,就需要 四个小时了,超过了规定时间,答案就不对了
3. 再一个方法,按照排列组合的方式,将16瓶水进行编号:分别编号0------15,上一个(二分法中)方法中,我们使用4瓶水就找到了有毒的水,那我们能不能用4瓶水在一个小时内找出有毒的水是哪一瓶呢?
下面,把水编号 0# -------- 15# 分别取样分成四组,如下:
每一组的试验结果只有两种情况,青蛙死亡和青蛙没死,我们把青蛙死亡标识为1 ,把没有死标识为0 ,那么最终四组试验共有以下16种结果:
把第1组到底4组的4个状态码组合起来,刚好是4个二进制码;注意看,从上往下,发现刚好可以表示成 0-----15,这与瓶子的编号对应
这样:我们可以得到结论:
当四个状态码组合结果为对应的值为0时,则 0# 号瓶子中的水有毒;当四个状态码组合结果值为1时,则1# 瓶子中的水有毒;当四个状态码组合结果值为2#,则2#瓶子中的水有毒............依此类推
共计需要4只青蛙
这样,四个分组同时试验,就可以在一个小时内将有毒的水找出来了
小结:此处是16个瓶子,然后需要4只试验青蛙,即 2n 个瓶子,然后需要 n 只试验青蛙;
验证:2个瓶子(21)需要 1 只青蛙;4个瓶子(22)需要 2 只青蛙;8个瓶子(23)需要 3 只青蛙;16个瓶子(24)需要 4 只青蛙,还可以往下推,结果是正确的。所以,可以得出一下结论:
2n 个瓶子中有一个瓶子中有毒,然后需要 n 只试验青蛙,就可以在最短的时间内将有毒的水是哪一瓶找出来