老鼠试药问题

来源:互联网 发布:邻里中国网php面试题 编辑:程序博客网 时间:2024/05/16 07:49
问题:
现有一千瓶药水,其中九百九十九瓶是完全一样的,只有一瓶里面是毒药,但是外观上分辨不出来。毒药给小白鼠喝了后,一星期后这只小白鼠会突然死亡,但之前一点症状也没有。现需要在一星期后找出哪瓶是毒药,问至少需要几只小白鼠?

这是一个求最优解的问题。这个问题需要把一个老鼠能使用的信息用到极致,即能达到最优解。

问题解析:
巧妙利用二进制编号是这道问题的关键
1.给每个瓶子用二进制编号,总共有1000瓶,2的10次方等于1024,只需用十位二进制就可表示所有的瓶子,每一位依次用w1、w2、…w10表示。 
2.给每个老鼠编号,c1、c2、…c10分别给十只老鼠编号,

编号c1的老鼠只喝w1位上为1的药水瓶,编号c2的老鼠只喝w2位上为1的药水瓶,依次类推。
即c1号老鼠和掉的药为,1000000001,1000000010,1000000011.....
最后看哪些老鼠死掉,例如c10、c8、c7、c4、c3、c1编号的老鼠死掉,那么有毒药水的编号就是10 1100 1101
如果所有老鼠都没意死,那么说明毒药的二进制编号为0000000000。


简化一下:如果只有8瓶,至少需要几只老鼠???
药水瓶编号是000 001 010 011 100 101 110 111,
三位二进制w1、w2、w3
三只老鼠是c1、c2、c3,
老鼠c1、c2、c3与三位二进制w1、w2、w3一一对应
c3喝: 100 101 110 111(右数第三位是1的都喝)
c2喝: 010 011 110 111(右数第二位是1的都喝)
c3喝: 001 011 101 111(右数第一位是1的都喝)

最后假设c3死了c2c1正常,那么100是毒药
假设c3c2死了,那么110是毒药 
如果c1,c2,c3均没死,那么毒药的二进制编号为000
类推,哪只老鼠死对应位上就是1,没死为0,得出的结果就是毒药瓶编号


再将此问题稍作一点改变:

问:

32瓶液体,1瓶有毒,老鼠喝了1小时死亡,用1小时确定至少30个瓶子无毒,至少需要多少老鼠?

同上面的解法类似,我们只需要计算2的多少次幂是32,也就是说,最少5只老鼠可以确定32瓶液体中,哪一瓶是毒药。

可是问题要求的是:至少30瓶无毒。

对于这个问题,仍按照上面的解法,只需4只老鼠就可以了。

把32瓶药水两两绑在一起,变成了16大瓶。

将16瓶药水编号:0000  0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100  1101 1110 1111

老鼠c1喝:1000 1001 1010 1011 1100 1101 1110 1111  (左数第一位为1)

老鼠c2喝:0100 0101 0110 0111 1100 1101 1110 1111  (左数第二位为1)

老鼠c3喝:0010 0011 0110 0111 1010 1011 1110 1111   (左数第三位为1)

老鼠c4喝:0001 0011 0101 0111 1001 1011 1110 1111   (左数第四位为1)

一小时后,如果有老鼠死了,则把对应位置填1,没死则填0,这样可以在一个小时后,得到一个二进制数。在确定下一瓶液体有毒后,就可以确定其他30瓶无毒了,完成目标。如果没有任何老鼠死亡,则编号0000液体有毒,剩下30 瓶无毒,完成目标。



原创粉丝点击