老鼠试毒

问题

  1. # 假设有1000瓶药水,其中有一瓶是毒药,注射在小白鼠身上24小时以后死亡,如何快速,高效,低成本的找出这瓶毒药?

00001_老鼠试毒 - 图1

方法一

相信很多人都能想到第一种方法

  1. # 找1000只小白鼠,挨个注射过去,24小时以后,哪只小白鼠死亡,哪瓶药水就是毒药

00001_老鼠试毒 - 图2

但是假设这种药水是治疗猪的一种药水,只能和猪进行作用反应,或者是牛,那么按照我们的方法一,就需要1000头猪,或者1000头牛,假设一头猪或者一头牛的价值1000,1000头就是 1000*1000=1 000 000,一百万。我们的实验成本很高。

如何用较低的成本来完成这个实验呢?有人也会想到第二种方法

方法二

  1. # 找1只小白鼠,每天注射一种药水。哪天小白鼠死亡,那么那天的药水就是毒药

00001_老鼠试毒 - 图3

这种方法就很凭运气,运气好,第一天就能找到毒药,运气不好,第999天才能找到毒药。【如果第999天都没有小白鼠死亡,说明第1000瓶药水是毒药】

而且这种方法实验完需要 1000/365=2.7397260274,大概要3年左右的时间。

当然也有很多人能想到方法三,方法四

方案 小白鼠(只) 时长(天)
方法一 1000只小白鼠,只花1天 1000 1
方法二 1只小白鼠,花1000天 1 1000
方法三 10只小白鼠,100天 10 100
方法四 100只小白鼠,10天 100 10
程序员 二进制法 10 1

那我们程序猿都知道的二进制法。可以只花10只小白鼠,只用1天即可完成该实验。

二进制法

我们有10只小白鼠,

给10只小白鼠分别标号1,2,4,8,16,32,64,128,256,512

给药水编号,1,2,3,4,5,6,7…

1号药水注射到编号为1的小白鼠身上,

2号药水注射到编号为2的小白鼠身上,

3号药水,发现并没有编号为3的小白鼠,将第一只和第二只小白鼠编号加起来等于3,将药水注射到该2只小白鼠身上,

4号药水注射到编号为4的小白鼠身上,

5号药水,发现并没有编号为5的小白鼠,将第一只和第三只小白鼠编号加起来等于5,将药水注射到该2只小白鼠身上,

6号药水,发现并没有编号为6的小白鼠,将第二只和第三只小白鼠编号加起来等于6,将药水注射到该2只小白鼠身上,

7号药水,发现并没有编号为5的小白鼠,将第二只,第三只,第四只小白鼠编号加起来等于7,将药水注射到该7只小白鼠身上,

8号药水注射到编号为8的小白鼠身上,

假设2号药水有毒,那么凡是注射2号药水的小白鼠都会死亡,那么就是第1只和第2只会死亡,

凡是注射了有毒药水的老鼠就会死亡,换言之,死亡的老鼠身上的编号加起来就是药水的编号,我们发现1000号药水仅用到了6只老鼠,

那么试问一下,如果所有的老鼠都死亡说明这药水的编号是多少呢?答案:1023=512+256+128+64+32+16+8+4+2+1

00001_老鼠试毒 - 图4

00001_老鼠试毒 - 图5

表格如下:

第10只 第9只 第8只 第7只 第6只 第5只 第4只 第3只 第2只 第1只 药水编号
512 256 128 64 32 16 8 4 2 1
1 1
1 2
1 1 3
1 4
1 1 5
1 1 6
1 1 1 7
1 8
1 1 1 1 326
1 1 1 1 1 1 1000
1 1 1 1 1

将注射药水的老鼠标号为1,没有注射的标号为0,得到一个 0101的数列,这个数列就是 二进制。

如果很多 1111101000 这样写很不容易读,非常容易读错,所以4个分一下 0011 1110 1000,前面不足四位的,补零

00001_老鼠试毒 - 图6

打开计算器

00001_老鼠试毒 - 图7

00001_老鼠试毒 - 图8

验算 十进制的 326 是否等于 二进制的 0001 0100 0110

00001_老鼠试毒 - 图9

00001_老鼠试毒 - 图10

练习题

写出 235 的二进制

答案:1110 1011

写出 1011 0111 的十进制

答案:183