计算思维—小白鼠试验毒药(底层思路)—二分法怎么分—二进制思维

目录

1.0问题引入

2. 0问题解决

2.1简单的情况: 

2.1.1分析

2.1.2 两个角度

       从小白鼠的角度

综合小白鼠角度

从水瓶的角度

深层理解

3.0问题回归

4.0方法提炼

5.0小结



1.0问题引入

        相信你思考过这样一个问题:

        有1000瓶水,其中一瓶是有毒的,小白鼠只要尝一点带毒的水24h就会死亡。

        问题:至少需要多少只小白鼠才能在24h内检验出那瓶水有毒?怎样检验?


        我们通常会用“二分法”解决。

        将1000瓶水按照 000, 001,002, 003,...... 997,998, 999 依次编号,对前500瓶用一只小白鼠检验,然后确认有毒的水是否在这500瓶内;

        在筛选出的剩余500瓶水中,继续前250用一只小白鼠检验,后250瓶用另一个小白鼠检验;

        然后,前125,后125;

        ......

        等等,真的是这样吗?

        答案是否定的,因为检验一次就需要24h,时间一定超出限制,不符合题意。

        我们按照平时的思路对检验对象进行区分(将多个对象分批进行检测),发现是行不通的。

        其实,这就是没有真正理解二分法的本质,没有根据正确的标准对白鼠进行区分。在你理解本文之后,就会发现仅仅按照编号,采用类似 "对区间二分" 的方法来解决本题是多么的天真。

        在这里我们先解决问题,对二分法的讨论放在文章后半部分


2. 0问题解决

        当我们理解了二进制的思维,用二进制思维来解决问题,就会发现容易的多:

        我们知道,n位二进制可以表示2^n(C语言不能这样写)瓶水,0-999这1000个编号转换成二

进制需要10个二进制位,即2^9 <1000 < 2^10,因此需要十只小白鼠来对每个二进制位编号。

        但到这里,我们发现思路断了,在解决这个比较复杂的问题之前,我们先看一种相对简单情况:


2.1简单的情况: 

         有8瓶水,用小白鼠验毒,24h内要得出结果。

        我们先用小白鼠将二进制位编号:(从右向左升序)

接下来,按规则:

        1. 每瓶水的编号的每一位(只能是1或0)代表对应位的小白鼠  是否喝这瓶水(1—包含;0—不包含);

        e.g.(编号为110的瓶子——则第一只不喝,第二只喝,第三只喝)

        2.开始试验并操作;

        3.根据结果,若小白鼠死亡,则这只小白鼠编号的二进制位记为1,否则记为0;

        4.确定每一二进制位的“状况”(0或1);

        5.将最终的二进制数换算成十进制数再+1,即为有毒的水的十进制编号。(二进制从0开始编号)

        或许你无法得知这样的操作得到的结果是否可靠,它的原理是什么?


2.1.1分析

2.1.2 两个角度

        本问题只有两个对象,于是可以从两个对象出发,分析并解决问题。并且,两个思路虽然不同,但都达到了解决问题的目的。


       从小白鼠的角度

        用小白鼠将二进制位编号:(从右向左升序)

        我们可以将水瓶按照一定的标准来分组:(见标注)

        { 10 1 ,00 1 ,11 1 ,01 1   }        { 10 0 ,00 0 ,11 0 ,01 0  }

        {  1 0 ,0 0 ,1 1 ,0 1 }    { 1 0 ,0 0 ,1 1 ,0 1  }        

        { 00 ,01 ,10 ,11  }        {  00 ,01 ,10 ,11  }

        我们可以发现规律:(从右向左看)

        第一行的 二进制 的第一位 相同,左侧的一组为1,右侧的一组为0;

        类似的:

        第二行的 二进制 的第二位 相同,左侧的一组为1,右侧的一组为0;

        第三行的二进制 的第三位 相同,左侧的一组为1,右侧的一组为0;

        假设101号有毒,我们知道喝了这瓶水的小白鼠为1号 ,3号,同时2号没有喝,最后结果是1和3号死亡,2号存活,那么毒水的编号就是101。

已知结果,透明地来看待问题是不是有点奇怪?

        别急,接下来我们正向思考:

        二进制的 0 表示 不喝水,没有毒, 没有死亡。

        如果一只小白鼠死亡,可以确定的是它一定是喝了对应二进制位上的水:

        如果第二个二进制位对应的小白鼠没有死,则说明它喝的水(第二位编号为1)中没有有毒的水:

        注意,这里结论不同了——水瓶编号第二位为1的水瓶集合里面没有有毒的水。也就是是说这四瓶水没有毒——110 ,010 ,111 ,011。

 

        依次第三个二进制位对应的小白鼠死了,则说明它喝的水(第三位编号为1)中有有毒的水:

        注意,这里的结论与第一种相同——水瓶编号第三位为1的水瓶集合中有有毒的水。也就是说这四瓶水有有毒的水——100 ,101 ,110 ,111。

综合小白鼠角度

        综合以上三条结论,有毒的水不在110 ,010 ,111 ,011中,有毒的水在101,001,111,011或者100 ,101 ,110 ,111中。

        于是得出结论101号有毒。

从水瓶的角度

        对每瓶水,它要分为若干份,比如编号为101的水瓶:

        要分给1号与3号小白鼠喝。

        毒水瓶的编号是确定的,关键就是要确定这个编号,也就是确定毒水瓶的每一个二进制位。

        一个小白鼠就相当于一个检验机制,一只小白鼠的状态反应(死/活),就可以确定毒水 的这个二进制位的数字(1/0),于是三只小白鼠就可以确定毒水瓶的编号。

深层理解

        如果:

        对水瓶,小白鼠喝了它,判断为1;

        水瓶有毒,判断为1;

        对小白鼠,死亡判断判断为1;

        那么:

        

        一只小白鼠的死(死亡判断为1)可以推知——它喝了水(喝水判断为1),并且水瓶有毒判断为1,于是小白鼠的死就与水瓶有毒都可用1来表示。


3.0问题回归

        我们将十个二进制位用十只小白鼠分别编号,根据试验结果判断小白鼠对应二进制位的两种状态(真与假),于是就得到了毒水的二进制编号。

4.0方法提炼

        二分法到底怎么分?

        平常思维

        当工人检修电缆时,先从中点检测,于是可以确定是哪半段出现了问题,进而依次类推,当C语言实现有序数组二分查找,也是先将数组中间项与第一项和最后一项比较,进而确定要查找的一项位于哪半段数组。

        二分法思维

        我们每次都将问题的结果分为可能与不可能两种情况,然后排除所有不可能的情况,并在可能的情况中再进行下一次的排除的方法思维。

        其实生活中有很多问题的结果都有两种,比如做核酸检测的结果,可以变成————

        有1000个人,他们相互隔离,其中有1人感染病毒,做一次核酸得到结果需要5h,要求在5h内确定这个人是谁?

        同样可以用二进制思维处理,但事实往往是很多人都感染了病毒,并且将1000个人一一隔离并不现实,虽然二分思维省时省力,但现实中不适用。

5.0小结

        二分法是否能够应用到实际问题需要判断:

        一般是有一个检验机制,通过检验机制可以反映检验对象的两种对立的状态,则可用n个这样的检验机制,分别编号二进制位,根据检验结果,来确定对应二进制位的状态(0/1),从而解决问题。


完。

希望本文对你有所帮助

未经作者同意禁止转载。

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

水墨不写bug

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

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

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

打赏作者

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

抵扣说明:

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

余额充值