首页
社区
课程
招聘
[原创]最近微博里很热的1000瓶子10小白鼠找毒药问题
发表于: 2012-3-29 22:27 7131

[原创]最近微博里很热的1000瓶子10小白鼠找毒药问题

2012-3-29 22:27
7131
有 1000 个一模一样的瓶子,
其中有 999 瓶是普通的水,有一瓶是毒药。
任何喝下毒药的生物都会在一星期之后死亡。
现在,你只有 10 只小白鼠和一星期的时间,
如何检验出哪个瓶子里有毒药?


原帖地址
http://www.zhihu.com/question/19676641

提示:使用伟大的二进制

从1000个瓶子跟10个老鼠这里直觉就是会跟2的10次方有关系
也学是学计算机的对二进制比较熟悉吧
联想到要用10这个数字来构造1000种可能而 2的10次方=1024>1000
而且每条老鼠的结果就两种可能被毒死而没被毒死
这个问题就把十个老鼠当作十个二进制的位,十位二进制能表示的数字个数是1024个,所以即使瓶子数量是1024也是可以找出来结果的,具体办法就是把一千个瓶子标上序号(先拿出来一瓶,剩下的瓶子从1开始编号),假设 是编号为n的有毒 比如n是 512那么 写成二进制就是1000000000,现在让你找这个序号是多少,相当于让你确定这个十位的二进制数每一位的数字是什么(此时你并不知道是512),so 我们先来确定第一位,我们使用正向确定法,就是确定这位是不是1(反向推测就是确定这位是不是0),怎么确定呢,我们先找到这一位是1的所有的数值,然后把这些数值对应的瓶子里面的液体取出来混合,(此时一就是512一直到99)让第一个老鼠喝掉,然后第二位,第三位.....依次类推到最后一位。最后十个老鼠都喝了瓶子的液体,一周后,哪个老鼠死了那一位就是1,得到一个十位的二进制数字,转换成十进制就搞定了,比如我们之前举的例子是编号512这瓶,那么肯定就是只有第一个老鼠死了,得到结果是1000000000

(如果任何老鼠都没有死即结果是0000000000 ,就是说明我们拿出来的那瓶是毒药)



附上1000苹果问题的一点解答的想法
题目】 1000个苹果放入10个箱子。客户如果要获得1~1000个苹果中的任意个数,都可以整箱搬,而不用拆开箱子。问是否有这样的装箱方法?
你说的1000苹果是这个问题吧?
这个题目直观多了
其实这个跟我们学的那个什么信息安全里面的某些问题到时有异曲同工之妙,也跟之前那个金条分三段发七天工资的问题差不多
这个相对于找毒药问题比较简单,首先即使你不懂也能有思路,首先1肯定得有因为它不可能得于任何自然数的和之后你发现2也不能如果你分两个箱子为1岂不是很浪费so 你有了1 2 你就有了 3 so 你应该发现点规律了吧 不行的话你继续 分一个4 1 2 4 你能组合小于8的任何数
so 你应该明白了吧 其实 1 2 4 8 16 这种数是可以构造任意数值的 因为 你首先知道 二进制 是可以表示任何整数的
二进制每一位都是对应前面的1 2 4 8 所以你有了1 2 4 8 16 就相当于 你有了 这几位的二进制 当客户提出一个整数的时候你就把他转化成
二进制比如客户想要127个 也就是 1111111 那你就取 1 2 4 8 16 32 64的箱子给他 就行了

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (28)
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
2
伟大的程序员!
2012-3-29 22:44
0
雪    币: 237
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
思路可以发散出来。
2012-3-29 23:15
0
雪    币: 2503
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
在思考这个思路 有一点眉目
2012-3-29 23:43
0
雪    币: 967
活跃值: (1138)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
佩服 你太有才了
2012-3-30 00:02
0
雪    币: 102
活跃值: (54)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
瓶子2进制编号,第n只老鼠负责所有第n位为1的瓶子
2012-3-30 00:06
0
雪    币: 327
活跃值: (446)
能力值: ( LV12,RANK:236 )
在线值:
发帖
回帖
粉丝
7
个人认为这个应该是大学数字电路的译码器的一个变通的灵活运用。
在这个例子中,3-8译码器正向的情况是3输入A3-A2-A1,将产生8输出。
受A3控制的是1XX即是(4、5、6、7),受A2控制的是X1X即是(2、3、6、7),受A1控制的是XX1即是(1、3、5、7)。
显然可以得出一个结论,
(4、5、6、7)有效则A3肯定是1,否则A3是0;
(2、3、6、7)有效则A2肯定是1,否则A2是0;
(1、3、5、7)有效则A1肯定是1,否则A1是0;
因此这3组集合肯定可以唯一确定,A3-A2-A1,即是可以唯一确定是哪个编号有问题!

以下是数电的内容:
一. 译码器

    译码器的功能是对具有特定含义的输入代码进行"翻译",将其转换成相应的输出信号。
    译码器的种类很多,常见的有二进制译码器、二-十进制译码器和数字显示译码器。

    1.二进制译码器

    (1) 定义
    二进制译码器:能将n个输入变量变换成2n个输出函数,且输出函数与输入变量构成的最小项具有对应关系的一种多输出组合逻辑电路。

   (2) 特点
      ● 二进制译码器一般具有n个输入端、2n个输出端和一个(或多个)使能输入端。
      ● 在使能输入端为有效电平时,对应每一组输入代码,仅一个输出端为有效电平,其余输出端为无效电平(与有效电平相反)。
      ● 有效电平可以是高电平(称为高电平译码),也可以是低电平(称为低电平译码)。

    (3) 典型芯片
    常见的MSI二进制译码器有2-4线(2输入4输出)译码器、3-8线(3输入8输出)译码器和4-16线(4输入16输出)译码器等。图7.7(a)、(b)所示分别是T4138型3-8线译码器的管脚排列图和逻辑符号。
上传的附件:
2012-3-30 00:08
0
雪    币: 159
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
没有关注过这个问题。
2012-3-30 08:27
0
雪    币: 1085
活跃值: (114)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
9
思路很别致。不错。
2012-3-30 09:28
0
雪    币: 27
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
你下面举得例子,如果第6个瓶子是的话,你知道是哪个?  一次死俩?3和5和6都掺了两次。
2012-3-30 09:43
0
雪    币: 2290
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
很好很强大的二进制啊,现在都忘光了
2012-3-30 09:46
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
看来你没明白啊
就是根据最后小白鼠死亡的结果来判定的
不同的死亡结果对应不同的瓶子编号
如果是六 那就是 110 就是前两个小白鼠都死了
如果三个都死了 说明是第七瓶
注意不是根据某个死了来确定的
而是根据十个小白鼠综合起来的死亡结果来判定的
每一个小白鼠负责判定对应的二进制位是零还是一
最后根据小白鼠生存结果来得到一个十位的二进制数
比如1111111111 那么就是说明编号为 1111111111=2的10次方减1=1023的那瓶
对应到上面的8瓶三只老鼠的情况就是111 也就是有毒的是编号为7的那瓶
你找找肯定是三个里面都有的就是编号为7的那瓶
2012-3-30 10:04
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
这样说也未尝不可
反正都是差不多 因为每个开关的输入也就是只有两种
不过解决这个问题想到数学上的(应该是计算机里面的)二进制就行了
一般来说比较不太可能会想到那里,除非是跟逻辑电路打交道比较多的硬件人员
2012-3-30 10:07
0
雪    币: 27
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
3Q,刚才没考虑跟二进制关联起来的问题。现在明白了
2012-3-30 10:08
0
雪    币: 20825
活跃值: (4035)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
This is great !
Thank you very much
2012-3-30 10:28
0
雪    币: 102
活跃值: (54)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
既然只要2^10=1024种老鼠状态中的1000种无冗余的代表1000种瓶子的可能结果(一一对应),检验方法肯定不是唯一的。
那么共有多少种检验方法?
????????????????????????????????????????????
2012-3-30 11:58
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
17

使用的是二进制 二进制每一位就两种可能
0 或者 1
虽然说有毒的瓶子的编号知道之前是有1000中可能的
但是二进制的表示方式就两种可能要么正常的1 就代表 1
要么反向的 0 代表 1 看起来是十位但是十位肯定使用的是同样的表示方式了
所以冗余并不能被利用
也就无法扩展其他的表示方式
比如 你想使用冗余的输出可能
假设你想使用 是 1111111111 =1023  这个结果
那么 按照之前我说的 1111111111 要么表示 1111111111  
要么表示0000000000
因为在你结果的十位二进制数中0代表 1 还是代表0 必须是固定的
不能你的十位二进制数中 第一位代表0 第二位又代表1去了

除非你的瓶子数低于1024的一半
那你就能使用相反的表示方式了
2012-3-30 15:31
0
雪    币: 102
活跃值: (54)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
举个例子:
共5瓶(编号1-5)
老鼠1喝:4,5
老鼠2喝:2,3
老鼠3喝:1,3,5;
或者
老鼠1喝:4,5,2
老鼠2喝:2,3
老鼠3喝:1,3,5;
随便写的,应该不错吧
2012-3-30 16:02
0
雪    币: 255
活跃值: (342)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
是楼主没有把话讲明白,根据我的理解,这样讲,可能更容易明白:
1.把1-3号小白鼠的排列看成一个2进制记数器,活着代表0,死了代表1(这里是一个3位数的2进制记数器);
2.先假设这个2进制记数从001开始记数,每增加一个记数,把这个2进制记数器所对应的十进制数,填入到记数位上凡显示有1的下面的分组圈里,完成分组,共分3组;
3.按照分组,开始混合,给对应编号的小白鼠吃,如1、3号死了,2进制记数器显示为101,对应的十进制数为5,即5号瓶有毒;如果1只都没有死,2进制记数器显示为000,即编号为0的哪瓶有毒。
4.以此类推,当二进制记数器增加到4位时、5位。。。时直到10位时,均可按此方法完成分组。达到10位后,从左至右,如果第1、第5 、第7、第9和第10位上的小白鼠死了,其他位的没有死,记数器则表示为1000101011,换算成10进制即为555,也就是第555号瓶有毒。呜。。。
2012-3-30 16:13
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
20
那么如果是编号为2的有毒 那么你是怎么判断那瓶有毒呢
老鼠 1 2 都死了
1 3 5 没毒 那么 是 4  还是 2呢?
2012-3-30 17:08
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
21
直观来说是这样,不过我只不过是先安装自己的做这道题目的时候的思路来写罢了

就好像老师教学生一样,大部分老师总是教给学生这个问题这样可以解决
但是并没有告诉我们为什么这样能解决
为什么第一个做出这道题目的人是怎么想出来的
总不可能一下子就知道这样就能做出来来了
总得有个思路过程吧是吧
所以授人以鱼不如授人以渔
让别人看到你的思路过程,才能有进步
2012-3-30 17:12
0
雪    币: 120
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
这个程序写出来很有意思。。。

原贴的3鼠8瓶解释的很清晰。
根据2^10=1024,所以10个老鼠可以确定1000个瓶子具体哪个瓶子有毒。具体实现跟3个老鼠确定8个瓶子原理一样。
000=0
001=1
010=2
011=3
100=4
101=5
110=6
111=7
一位表示一个老鼠,0-7表示8个瓶子。也就是分别将1、3、5、7号瓶子的药混起来给老鼠1吃,
2、3、6、7号瓶子的药混起来给老鼠2吃,4、5、6、7号瓶子的药混起来给老鼠3吃,哪个老鼠
死了,相应的位标为1。如老鼠1死了、老鼠2没死、老鼠3死了,那么就是101=5号瓶子有毒。
2012-3-30 17:20
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
23
我 同学有人拿 PHP 实现了 用户输入瓶子个数
它就能输出 需要的老鼠个数
以及每个老鼠 要喝的任务
最后你提交一种老鼠死亡的结果
就可以判定哪瓶是有毒的
2012-3-30 17:22
0
雪    币: 120
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
好像看看代码的逻辑。。。1000瓶那得多少判断啊。。。如果代码要写的很精炼,那还真不简单。
2012-3-30 17:24
0
雪    币: 275
活跃值: (51)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
25
因为他是搞PHP的 所以我也没 去看
不过貌似 蛮多循环的样子
2012-3-30 17:29
0
游客
登录 | 注册 方可回帖
返回
//