zoukankan      html  css  js  c++  java
  • 记一个有趣的二进制面试题------青蛙喝水

    有看到一个程序员的面试题,觉得很有趣,这里贴出来分享:

    试验室有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 只试验青蛙,就可以在最短的时间内将有毒的水是哪一瓶找出来

  • 相关阅读:
    Java类 初始化块
    Java中 equals和==
    Raft算法
    OLTP与OLAP
    数据库事务机制ACID
    乐观锁和悲观锁
    SparkStreaming + Flume
    如何提高深度睡眠质量,科学解决睡眠问题
    centos 7 下安装mysql 远程连接出现10038错误如何解决
    CentOS 7.0 yum安装Apache、PHP和MySQL
  • 原文地址:https://www.cnblogs.com/huanying2015/p/8630811.html
Copyright © 2011-2022 走看看