目录
1.0问题引入
2. 0问题解决
2.1 分析
2.1.1 两个角度
从小白鼠的角度
综合小白鼠角度
从水瓶的角度
深层理解
3.0问题回归
4.0方法提炼
5.0小结
在某一刻,初入大学的你,接触计算思维,从而打开了自己尘封已久的思维的大门,这一刻对渴望提升计算思维的你产生了很大的鼓舞。
相信大家都思考过这样一个问题:
有1000瓶水,其中一瓶是有毒的,小白鼠只要尝一点带毒的水24h就会死亡。
问题:至少需要多少只小白鼠才能在24h内检验出那瓶水有毒?怎样检验?
其实,我们探寻自己的思维轨迹,可以用“二分法”解决。
将1000瓶水按照 000, 001,002, 003,...... 997,998, 999 依次编号,对前500瓶用一只小白鼠检验,然后确认有毒的水是否在这500瓶内,接下来依次类推。
等等,真的是这样吗?答案是错的,因为检验一此就可能需要24h,时间会超出限制,不符合题意。
这时我们发觉,我们平时使用二分法不就是这样吗?
在这里我们先解决问题,对二分法的讨论放在文章后半部分。
当我们理解了二进制的思维,用二进制思维来解决问题,就会发现容易的多:
我们知道,n位二进制可以表示2^n(C语言不能这样写)瓶水,0-999这1000个编号转换成二
进制需要10个二进制位,即2^9 <1000 < 2^10,因此需要十只小白鼠来对每个二进制位编号。
但到这里,我们发现思路断了,不知道怎样处理了,别着急,我们先看一种简单情况:
有8瓶水,用小白鼠验毒,24h内要得出结果。
我们先用小白鼠将二进制位编号:(从右向左升序)
接下来,按规则:
1. 每瓶水的编号的每一位(只能是1或0)代表对应位的小白鼠 是否喝这瓶水(1—包含;0—不包含);
e.g.(编号为110的瓶子——则第一只不喝,第二只喝,第三只喝)
2.开始试验并操作;
3.根据结果,若小白鼠死亡,则这只小白鼠编号的二进制位记为1,否则记为0;
4.确定每一二进制位的“状况”(0或1);
5.将最终的二进制数换算成十进制数再+1,即为有毒的水的十进制编号。(二进制从0开始编号)
本问题只有两个对象,于是可以从两个对象出发,分析并解决问题。
并且,两个思路虽然不同,但都达到了解决问题的目的。
用小白鼠将二进制位编号:(从右向左升序)
我们可以将水瓶按照一定的标准来分组:(见标注)
{ 10 1 ,00 1 ,11 1 ,01 1 } { 10 0 ,00 0 ,11 0 ,01 0 }
{ 1 1 0 ,0 1 0 ,1 1 1 ,0 1 1 } { 1 0 0 ,0 0 0 ,1 0 1 ,0 0 1 }
{ 1 00 ,1 01 ,1 10 ,1 11 } { 0 00 ,0 01 ,0 10 ,0 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。
综合以上三条结论,也就是集合的关系运算,得出结论101号有毒。
对每瓶水,它要分为若干份,比如编号为101的水瓶:
要分给1号与3号小白鼠喝。
毒水瓶的编号是确定的,关键就是要确定其编号,也就是确定毒水瓶的每一个二进制位。一个小白鼠就相当于一个检验机制,一只小白鼠的状态反应(死/活),就可以确定毒水 的这个二进制位上 是(1/0),于是三只小白鼠就可以确定毒水瓶的编号。
如果:
对水瓶,小白鼠喝了它,判断为1;
水瓶有毒,判断为1;
对小白鼠,死亡判断判断为1;
那么:
一只小白鼠的死(死亡判断为1)可以推知——它喝了水(喝水判断为1),并且水瓶有毒判断为1,于是小白鼠的死就与水瓶有毒都可用1来表示。
我们将十个二进制位用十只小白鼠分别编号,根据试验结果判断小白鼠对应二进制位的两种状态(真与假),于是就得到了毒水的二进制编号。
二分法到底怎么分?
平常思维
当工人检修电缆时,先从中点检测,于是可以确定是哪半段出现了问题,进而依次类推,当C语言实现有序数组二分查找,也是先将数组中间项与第一项和最后一项比较,进而确定要查找的一项位于哪半段数组。
二分法思维
我们每次都将问题的结果分为可能与不可能两种情况,然后排除所有不可能的情况,并在可能的情况中再进行下一次的排除的方法思维。
其实生活中有很多问题的结果都有两种,比如做核酸检测的结果,可以变成————
有1000个人,他们相互隔离,其中有1人感染病毒,做一次核酸得到结果需要5h,要求在5h内确定这个人是谁?
同样可以用二进制思维处理,但事实往往是很多人都感染了病毒,并且将1000个人一一隔离并不现实,虽然二分思维省时省力,但现实中不适用。
二分法是否能够应用到实际问题需要判断:
一般是有一个检验机制,通过检验机制可以反映检验对象的两种对立的状态,则可用n个这样的检验机制,分别编号二进制位,根据检验结果,来确定对应二进制位的状态(0/1),从而解决问题。
完。
希望本文对你有所帮助
未经作者同意禁止转载。