问题1:1000瓶水中有1瓶下了毒,老鼠只要喝一点点就会在一周之内死掉,问至少需要多少只老鼠,才能在一周之内找出是哪一瓶水有毒?(微软笔试题)
[解析]
假设有n只老鼠,则瓶数的上限N = 2 ^ n。将瓶子的10进制编号(0 - N-1)改为n位的2进制码,然后从左到右:让第1只老鼠喝所有编号的2进制码中第1位是1的瓶子中的水,第2只老鼠喝所有编号的2进制码中第2位是1的瓶子中的水,……,第n只老鼠喝所有编号的2进制码中第n位是1的瓶子中的水。这里取n=2示例:
瓶的编号 |
瓶的编号的2进制表示 |
是否喂给第1只老鼠(0,不喂;1,喂) |
是否喂给第2只老鼠(0,不喂;1,喂) |
0 |
00 |
0 |
0 |
1 |
01 |
0 |
1 |
2 |
10 |
1 |
0 |
3 |
11 |
1 |
1 |
这样,由第n只老鼠一周后的死活情况就可确定毒水瓶的编号的2进制码的左起第n位:老鼠死,第n位为1;老鼠活,第n位为0。
有毒的瓶 的编号 |
有毒的瓶的编号 的2进制表示 |
第1只老鼠是否会死 (0,不死;1,死) |
第2只老鼠是否会死 (0,不死;1,死) |
0 |
00 |
0 |
0 |
1 |
01 |
0 |
1 |
2 |
10 |
1 |
0 |
3 |
11 |
1 |
1 |
由此可以判断N瓶水只需log2 N只老鼠即可找出其中的毒药瓶。
问题2:1000瓶水中有1瓶下了毒,老鼠只要喝一点点就会在一周之内死掉,问至少需要多少只老鼠,才能在两周之内找出是哪一瓶水有毒?
[解析]
问题2与问题1的不同之处在于,问题2中老鼠可以参加两次实验,这样,每只老鼠就有死死(第1周死掉)、生死(第2周死掉)、生生(第2周后仍然活着)3种状态。问题1中每只老鼠只有生或死2种状态,所以对瓶子的编号采用了2进制,问题2中每只老鼠有3种状态,所以对瓶子的编号应采用3进制。
假设有n只老鼠,则瓶数的上限N = 3 ^ n。将瓶子的10进制编号(0 - N-1)改为n位的3进制码。
第1次实验:
从左到右:让第1只老鼠喝所有编号的3进制码中第1位是2的瓶子中的水,第2只老鼠喝所有编号的3进制码中第2位是2的瓶子中的水,……,第n只老鼠喝所有编号的2进制码中第n位是2的瓶子中的水。这里取n=2示例:
瓶的 编号 |
瓶的编号的 3进制表示 |
是否喂给第1只老鼠 (0,1,不喂;2,喂) |
是否喂给第2只老鼠 (0,1,不喂;2,喂) |
0 |
00 |
0 |
0 |
1 |
01 |
0 |
1 |
2 |
02 |
0 |
2 |
3 |
10 |
1 |
0 |
4 |
11 |
1 |
1 |
5 |
12 |
1 |
2 |
6 |
20 |
2 |
0 |
7 |
21 |
2 |
1 |
8 |
22 |
2 |
2 |
这样,由第n只老鼠第1周后的死活情况就可确定毒水瓶的编号的3进制码的左起第n位是不是2:老鼠死,第n位为2;老鼠活,第n位为0或1。
有毒的瓶 的编号 |
有毒的瓶的编号 的2进制表示 |
第1只老鼠是否会死 (0,1,不死;2,死) |
第2只老鼠是否会死 (0,1,不死;2,死) |
0 |
00 |
0 |
0 |
1 |
01 |
0 |
1 |
2 |
02 |
0 |
2 |
3 |
10 |
1 |
0 |
4 |
11 |
1 |
1 |
5 |
12 |
1 |
2 |
6 |
20 |
2 |
0 |
7 |
21 |
2 |
1 |
8 |
22 |
2 |
2 |
不妨假设毒水瓶的编号是5,则第1次实验的结果为第1只老鼠不死,第2只死掉,据此可判断出毒水瓶的编号的3进制码的左起第1位为0或1,第2位为2,所以可能的编号为2(02)或5(12)。
第2次实验:
对于所有还活着的老鼠,从左到右:让第1只老鼠喝所有编号的3进制码中第1位是1的瓶子中的水,第2只老鼠喝所有编号的3进制码中第2位是1的瓶子中的水,……,第n只老鼠喝所有编号的3进制码中第n位是1的瓶子中的水。
瓶的 编号 |
瓶的编号的 3进制表示 |
是否喂给第1只老鼠 (0,不喂;1,喂) |
2 |
02 |
0 |
5 |
12 |
1 |
这样,由第n只老鼠第2周后的死活情况就可确定毒水瓶的编号的3进制码的左起第n位:老鼠死,第n位为1;老鼠活,第n位为0。
有毒的瓶 的编号 |
有毒的瓶的编号 的2进制表示 |
第1只老鼠是否会死 (0,不死;1,死) |
2 |
02 |
0 |
5 |
12 |
1 |
问题3:N瓶水中有1瓶下了毒,老鼠只要喝一点点就会在一周之内死掉,现在由n只老鼠,问如果要求在第k周结束时找出是哪一瓶水有毒,N的最大值可以取多少?
[解析]
问题3中老鼠可以参加k次实验,这样,每只老鼠就有:第1周死掉,第2周死掉,……第k周死掉,第k周后仍然活着,共(k+1)种状态。所以对瓶子的编号应采用(k+1)进制。
假设有n只老鼠,则瓶数的上限N = (k+1) ^ n。将瓶子的10进制编号(0 - N-1)改为n位的(k+1)进制码。
第1次实验:
从左到右:让第1只老鼠喝所有编号的(k+1)进制码中第1位是k的瓶子中的水,第2只老鼠喝所有编号的(k+1)进制码中第2位是k的瓶子中的水,……,第n只老鼠喝所有编号的(k+1)进制码中第n位是k的瓶子中的水。
这样,由第n只老鼠第1周后的死活情况就可确定毒水瓶的编号的(k+1)进制码的左起第n位是不是k:老鼠死,第n位为k;老鼠活,第n位为0,1,……,(k-1)中的任意数。
第2次实验:
对于所有还活着的老鼠,从左到右:让第1只老鼠喝所有编号的(k+1)进制码中第1位是(k-1)的瓶子中的水,第2只老鼠喝所有编号的(k+1)进制码中第2位是(k-1)的瓶子中的水,……,第n只老鼠喝所有编号的(k+1)进制码中第n位是(k-1)的瓶子中的水。
这样,由第n只老鼠第2周后的死活情况就可确定毒水瓶的编号的(k+1)进制码的左起第n位是不是(k-1):老鼠死,第n位为(k-1);老鼠活,第n位为0,1,……,(k-2)中的任意数。
接下来的实验以此类推,一直进行到第k次实验为止。