7只老鼠測試100個瓶子


起源

  今天,休息的時候同事虎哥給我們說了一個很有意思的問題:有100個瓶子,瓶子里面乘着水,其中有一個瓶子里面的水是有毒的。還有七只老鼠,老鼠喝了有毒的水,七天會死掉。現在給你七天的時間,然后讓你用這七只老鼠將這些瓶子里面有毒的那個瓶子測試出來,怎么做?

  據說這個問題是某個比較大的公司的一個面試題。對這個問題很感興趣的,於是,下班回家后就開始研究這個問題,想到了現在(除去中間打了一把紅警的時間)終於想出來了,跟大家分享下。

思路

思路一:

  對於這個問題,我的第一個思路是這樣的(這個思路我沒有走通,有興趣的同學可以研究下。不感興趣的同學可以直接看第二個思路):七只老鼠,七天死亡,七天出結果。肯定不能一個一個的進行慢慢嘗試。否則這個問題就太簡單了。那么,解決問題的關鍵就出在了不同老鼠的組合之上了。比如說:一個老鼠吃一個葯,可以檢測出來七個瓶子。在數軸上表示為一個x軸。還是比較簡單的。

  然后我打算試一下讓一個老鼠吃兩個葯,希望可以得出一個二維數組,一個x軸一個y軸那樣的坐標軸。然后可以得出49個結果的一個矩陣如圖所示;(圖解:比如說,12,就代表着1號老鼠和2號老鼠都吃這個瓶子中的溶液。如果有且僅有兩個老鼠死亡,並且是1號老鼠和2號老鼠,則表示12對應的這個瓶子中的液體是有毒的。)

   

 

  但是,很快我就發現一些問題:首先,一個老鼠吃的不是2個瓶子的溶液,而是很多個瓶子。其次,里面的11,22,33等對應的坐標如果有毒的話,只會死掉一個老鼠,那么,就沒有辦法跟一個老鼠只吃一種葯的那7種情況做區別了。還有就是12號和21號,如果一個有毒的話,那么,沒有辦法確定是12號坐標對應的瓶子有毒還是21號坐標對應的瓶子有毒。兩個只能留一個。最終可以用的坐標只有21個圖中黃色區域:

 

  加上之前的七個一維數組,總共是28個可能,即可以測試28個瓶子。這時,我就想起了三維數組,再加一個z軸嘛。肯定會有一些重復的不能使用,於是我又畫了個三維數組。

 

   於是,這次又發現了三個老鼠死亡的時候,可以出現的可能。總共有35種可能。加上之前的28種可能,總共可以測試63個瓶子。然后就需要四維數組了。最后一直到七維數組,也就是七個老鼠都死亡的情況,但是感覺實施起來太蛋疼了。就想找個簡單點的解決方案。於是就有了以下:

思路二:

  在思路2開始之前,自己感覺很麻煩,正好小馬哥打電話過來,就問了下他有什么解決方法,他給了這個方案:將老鼠弄死,磨成肉泥,放到一百個瓶子里。最后哪個瓶子里面的肉沒有長蛆哪個就有毒。讓我佩服啊。

  好,扯淡完畢。說下思路二,也就是我的現在的解決方案。當時的想法是這樣的---為啥不考慮下老鼠的潛力呢?怎么個意思呢?老鼠有兩種狀態:1.喝了溶液。2.沒有溶液。

  那么一個老鼠可以測試一個瓶子的狀態:喝完了死了表示有毒,沒死表示沒毒。那么兩個老鼠呢?可以測試3個瓶子:1號老鼠喝一個,2號老鼠喝一個,倆老鼠一起喝一個。1號自己死了,表示第一個瓶子有毒;2號老鼠自己死了,表示2號瓶子有毒,哥倆一起死了表示3號瓶子有毒。

  以此類推,最后得出一個結論:七只老鼠總共可以測試2的7次方減1個瓶子,也就是說127個瓶子。如果確定肯定有一個瓶子是有毒的,那么可以檢測128個瓶子,因為可以留一個瓶子不給老鼠喝,沒有老鼠死就表示最后一個是有毒的。

  這讓我聯想到了二進制中的進位的算法。於是就用Java代碼模擬了下測試的過程。首先,定義七個integer值表示七只老鼠。對於每個瓶子中的液體,老鼠有兩種可能:1.喝了,2.沒有喝。

  然后,我定義了一個長度為100的數組,表示100個瓶子的集合。在數組中存放了100個瓶子對象,這些對象都有一個屬性,那就是是否有毒。true的時候是有毒的。這里隨機賦予一個瓶子為有毒的瓶子

  然后,我們根據二進制進位的方法開始給這些老鼠喂葯:先給1號老鼠喂葯,並將老鼠標號變為1.下一個循環的時候,發現1號老鼠標號是1於是給2號老鼠喂葯,並將1號的標號設置成0。類似於二進制的0-1進位的感覺。

  最后,一星期后,根據死亡的老鼠的標號看都是哪些老鼠死了比如說:4號老鼠和5號老鼠還有7號老鼠死了,那么我們可以得出一個這樣的數據:這個瓶子的標號的二進制表示為1011000 為啥呢,因為這三個老鼠死掉了,表示這三個老鼠喝了有毒的那個瓶子中的液體了。喝了液體,我們的標記是1,其他的沒有死掉我們標記是0。例如:第一個瓶子只有1號老鼠喝了那么標記號就是0000001,二號瓶子只有2號老鼠喝了那么標記號便是0000010.而它們的10進制表示正好是1和2.

  核心的原理就是,用老鼠作為標記位數,去表示瓶子的號碼。然后通過死亡的老鼠,得出瓶子的二進制表示法,然后推導出哪個瓶子是有毒的。

  代碼如下:

代碼

 

  1 package test;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 import java.util.Random;
  6 
  7 public class test {
  8 
  9     public static void main(String[] args) {
 10         // 七只老鼠 0代表活,1代表死
 11         Integer y = 0;
 12         Integer e = 0;
 13         Integer s = 0;
 14         Integer si = 0;
 15         Integer w = 0;
 16         Integer l = 0;
 17         Integer q = 0;
 18         // 隨機出來一個有毒的瓶子
 19         Random random = new Random();
 20 
 21         Integer youdupingzi = random.nextInt(100) % 100;
 22         // 100個瓶子
 23         List<Pingzi> listpingziList = new ArrayList<Pingzi>();
 24         for (int i = 0; i < 100; i++) {
 25             Pingzi pingzi = new Pingzi(); // 生成瓶子
 26             if (i == youdupingzi) { // 產生有毒的瓶子
 27                 pingzi.isYoudu = true;
 28                 System.out.println("向第" + youdupingzi + "號瓶子里面投毒");
 29             }
 30             listpingziList.add(pingzi);
 31         }
 32         // =========================得出有毒的瓶子
 33         String silaoshuString = "";
 34         int i = 1;
 35         while (true) {
 36             y++;
 37             String chiyaolaoshu = "";
 38             // 模擬給老鼠喂葯
 39             if (y == 2) {
 40                 e++;
 41                 y = 0;
 42                 if (e == 2) {
 43                     s++;
 44                     e = 0;
 45                     if (s == 2) {
 46                         si++;
 47                         s = 0;
 48                         if (si == 2) {
 49                             w++;
 50                             si = 0;
 51                             if (w == 2) {
 52                                 l++;
 53                                 w = 0;
 54                                 if (l == 2) {
 55                                     q++;
 56                                     l = 0;
 57                                     if (q == 2) {
 58                                         getDuyaoping(silaoshuString); // 全部遍歷完成以后,得出死老鼠都有哪些
 59                                         return;
 60                                     }
 61                                 }
 62                             }
 63                         }
 64                     }
 65                 }
 66             }
 67             if (y == 1) {
 68                 if (chiyaolaoshu.length() < 1) {
 69                     chiyaolaoshu = "1號老鼠";
 70                 } else {
 71                     chiyaolaoshu += "  和1號老鼠";
 72                 }
 73             }
 74             if (e == 1) {
 75                 if (chiyaolaoshu.length() < 1) {
 76                     chiyaolaoshu += "2號老鼠";
 77                 } else {
 78                     chiyaolaoshu += "  和2號老鼠";
 79                 }
 80             }
 81             if (s == 1) {
 82                 if (chiyaolaoshu.length() < 1) {
 83                     chiyaolaoshu = "3號老鼠";
 84                 } else {
 85                     chiyaolaoshu += "  和3號老鼠";
 86                 }
 87             }
 88             if (si == 1) {
 89                 if (chiyaolaoshu.length() < 1) {
 90                     chiyaolaoshu = "4號老鼠";
 91                 } else {
 92                     chiyaolaoshu += "  和4號老鼠";
 93                 }
 94             }
 95             if (w == 1) {
 96                 if (chiyaolaoshu.length() < 1) {
 97                     chiyaolaoshu = "5號老鼠";
 98                 } else {
 99                     chiyaolaoshu += "  和5號老鼠";
100                 }
101             }
102             if (l == 1) {
103                 if (chiyaolaoshu.length() < 1) {
104                     chiyaolaoshu = "6號老鼠";
105                 } else {
106                     chiyaolaoshu += "  和6號老鼠";
107                 }
108             }
109             if (q == 1) {
110                 if (chiyaolaoshu.length() < 1) {
111                     chiyaolaoshu = "7號老鼠";
112                 } else {
113                     chiyaolaoshu += "  和7號老鼠";
114                 }
115             }
116             if(i > 99){ // 7個老鼠測試100個瓶子有富余
117                 System.out.println("所有瓶子都測試過了");
118             }else{
119                 System.out.println("第" + i + "瓶子葯喂給了第" + chiyaolaoshu);
120                 if (listpingziList.get(i).isYoudu) { // 如果這瓶葯有毒
121                     System.out.println("============= 這瓶葯有毒第" + chiyaolaoshu + "老鼠一星期后死亡!");
122                     silaoshuString = q.toString() + l.toString() + w.toString() + si.toString() + s.toString()
123                     + e.toString() + y.toString(); // 得到一星期后的死亡老鼠編號
124                 }
125             }
126             i++; // 下一瓶葯測試
127         }
128     }
129 
130     private static void getDuyaoping(String silaoshuString) {
131 
132         String duyao = Integer.valueOf(silaoshuString, 2).toString();
133         System.out.println("經老鼠檢測,有毒的瓶子為:" + duyao);
134     }
135 
136     public static class Pingzi {
137         public boolean isYoudu = false;
138     }
139 }
老鼠與瓶子的代碼

 

得出輸出結果如下:

  1 向第88號瓶子里面投毒
  2 第1瓶子葯喂給了第1號老鼠
  3 第2瓶子葯喂給了第2號老鼠
  4 第3瓶子葯喂給了第1號老鼠  和2號老鼠
  5 第4瓶子葯喂給了第3號老鼠
  6 第5瓶子葯喂給了第1號老鼠  和3號老鼠
  7 第6瓶子葯喂給了第2號老鼠  和3號老鼠
  8 第7瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠
  9 第8瓶子葯喂給了第4號老鼠
 10 第9瓶子葯喂給了第1號老鼠  和4號老鼠
 11 第10瓶子葯喂給了第2號老鼠  和4號老鼠
 12 第11瓶子葯喂給了第1號老鼠  和2號老鼠  和4號老鼠
 13 第12瓶子葯喂給了第3號老鼠  和4號老鼠
 14 第13瓶子葯喂給了第1號老鼠  和3號老鼠  和4號老鼠
 15 第14瓶子葯喂給了第2號老鼠  和3號老鼠  和4號老鼠
 16 第15瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和4號老鼠
 17 第16瓶子葯喂給了第5號老鼠
 18 第17瓶子葯喂給了第1號老鼠  和5號老鼠
 19 第18瓶子葯喂給了第2號老鼠  和5號老鼠
 20 第19瓶子葯喂給了第1號老鼠  和2號老鼠  和5號老鼠
 21 第20瓶子葯喂給了第3號老鼠  和5號老鼠
 22 第21瓶子葯喂給了第1號老鼠  和3號老鼠  和5號老鼠
 23 第22瓶子葯喂給了第2號老鼠  和3號老鼠  和5號老鼠
 24 第23瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和5號老鼠
 25 第24瓶子葯喂給了第4號老鼠  和5號老鼠
 26 第25瓶子葯喂給了第1號老鼠  和4號老鼠  和5號老鼠
 27 第26瓶子葯喂給了第2號老鼠  和4號老鼠  和5號老鼠
 28 第27瓶子葯喂給了第1號老鼠  和2號老鼠  和4號老鼠  和5號老鼠
 29 第28瓶子葯喂給了第3號老鼠  和4號老鼠  和5號老鼠
 30 第29瓶子葯喂給了第1號老鼠  和3號老鼠  和4號老鼠  和5號老鼠
 31 第30瓶子葯喂給了第2號老鼠  和3號老鼠  和4號老鼠  和5號老鼠
 32 第31瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和4號老鼠  和5號老鼠
 33 第32瓶子葯喂給了第6號老鼠
 34 第33瓶子葯喂給了第1號老鼠  和6號老鼠
 35 第34瓶子葯喂給了第2號老鼠  和6號老鼠
 36 第35瓶子葯喂給了第1號老鼠  和2號老鼠  和6號老鼠
 37 第36瓶子葯喂給了第3號老鼠  和6號老鼠
 38 第37瓶子葯喂給了第1號老鼠  和3號老鼠  和6號老鼠
 39 第38瓶子葯喂給了第2號老鼠  和3號老鼠  和6號老鼠
 40 第39瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和6號老鼠
 41 第40瓶子葯喂給了第4號老鼠  和6號老鼠
 42 第41瓶子葯喂給了第1號老鼠  和4號老鼠  和6號老鼠
 43 第42瓶子葯喂給了第2號老鼠  和4號老鼠  和6號老鼠
 44 第43瓶子葯喂給了第1號老鼠  和2號老鼠  和4號老鼠  和6號老鼠
 45 第44瓶子葯喂給了第3號老鼠  和4號老鼠  和6號老鼠
 46 第45瓶子葯喂給了第1號老鼠  和3號老鼠  和4號老鼠  和6號老鼠
 47 第46瓶子葯喂給了第2號老鼠  和3號老鼠  和4號老鼠  和6號老鼠
 48 第47瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和4號老鼠  和6號老鼠
 49 第48瓶子葯喂給了第5號老鼠  和6號老鼠
 50 第49瓶子葯喂給了第1號老鼠  和5號老鼠  和6號老鼠
 51 第50瓶子葯喂給了第2號老鼠  和5號老鼠  和6號老鼠
 52 第51瓶子葯喂給了第1號老鼠  和2號老鼠  和5號老鼠  和6號老鼠
 53 第52瓶子葯喂給了第3號老鼠  和5號老鼠  和6號老鼠
 54 第53瓶子葯喂給了第1號老鼠  和3號老鼠  和5號老鼠  和6號老鼠
 55 第54瓶子葯喂給了第2號老鼠  和3號老鼠  和5號老鼠  和6號老鼠
 56 第55瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和5號老鼠  和6號老鼠
 57 第56瓶子葯喂給了第4號老鼠  和5號老鼠  和6號老鼠
 58 第57瓶子葯喂給了第1號老鼠  和4號老鼠  和5號老鼠  和6號老鼠
 59 第58瓶子葯喂給了第2號老鼠  和4號老鼠  和5號老鼠  和6號老鼠
 60 第59瓶子葯喂給了第1號老鼠  和2號老鼠  和4號老鼠  和5號老鼠  和6號老鼠
 61 第60瓶子葯喂給了第3號老鼠  和4號老鼠  和5號老鼠  和6號老鼠
 62 第61瓶子葯喂給了第1號老鼠  和3號老鼠  和4號老鼠  和5號老鼠  和6號老鼠
 63 第62瓶子葯喂給了第2號老鼠  和3號老鼠  和4號老鼠  和5號老鼠  和6號老鼠
 64 第63瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和4號老鼠  和5號老鼠  和6號老鼠
 65 第64瓶子葯喂給了第7號老鼠
 66 第65瓶子葯喂給了第1號老鼠  和7號老鼠
 67 第66瓶子葯喂給了第2號老鼠  和7號老鼠
 68 第67瓶子葯喂給了第1號老鼠  和2號老鼠  和7號老鼠
 69 第68瓶子葯喂給了第3號老鼠  和7號老鼠
 70 第69瓶子葯喂給了第1號老鼠  和3號老鼠  和7號老鼠
 71 第70瓶子葯喂給了第2號老鼠  和3號老鼠  和7號老鼠
 72 第71瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和7號老鼠
 73 第72瓶子葯喂給了第4號老鼠  和7號老鼠
 74 第73瓶子葯喂給了第1號老鼠  和4號老鼠  和7號老鼠
 75 第74瓶子葯喂給了第2號老鼠  和4號老鼠  和7號老鼠
 76 第75瓶子葯喂給了第1號老鼠  和2號老鼠  和4號老鼠  和7號老鼠
 77 第76瓶子葯喂給了第3號老鼠  和4號老鼠  和7號老鼠
 78 第77瓶子葯喂給了第1號老鼠  和3號老鼠  和4號老鼠  和7號老鼠
 79 第78瓶子葯喂給了第2號老鼠  和3號老鼠  和4號老鼠  和7號老鼠
 80 第79瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和4號老鼠  和7號老鼠
 81 第80瓶子葯喂給了第5號老鼠  和7號老鼠
 82 第81瓶子葯喂給了第1號老鼠  和5號老鼠  和7號老鼠
 83 第82瓶子葯喂給了第2號老鼠  和5號老鼠  和7號老鼠
 84 第83瓶子葯喂給了第1號老鼠  和2號老鼠  和5號老鼠  和7號老鼠
 85 第84瓶子葯喂給了第3號老鼠  和5號老鼠  和7號老鼠
 86 第85瓶子葯喂給了第1號老鼠  和3號老鼠  和5號老鼠  和7號老鼠
 87 第86瓶子葯喂給了第2號老鼠  和3號老鼠  和5號老鼠  和7號老鼠
 88 第87瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和5號老鼠  和7號老鼠
 89 第88瓶子葯喂給了第4號老鼠  和5號老鼠  和7號老鼠
 90 ============= 這瓶葯有毒第4號老鼠  和5號老鼠  和7號老鼠老鼠一星期后死亡!
 91 第89瓶子葯喂給了第1號老鼠  和4號老鼠  和5號老鼠  和7號老鼠
 92 第90瓶子葯喂給了第2號老鼠  和4號老鼠  和5號老鼠  和7號老鼠
 93 第91瓶子葯喂給了第1號老鼠  和2號老鼠  和4號老鼠  和5號老鼠  和7號老鼠
 94 第92瓶子葯喂給了第3號老鼠  和4號老鼠  和5號老鼠  和7號老鼠
 95 第93瓶子葯喂給了第1號老鼠  和3號老鼠  和4號老鼠  和5號老鼠  和7號老鼠
 96 第94瓶子葯喂給了第2號老鼠  和3號老鼠  和4號老鼠  和5號老鼠  和7號老鼠
 97 第95瓶子葯喂給了第1號老鼠  和2號老鼠  和3號老鼠  和4號老鼠  和5號老鼠  和7號老鼠
 98 第96瓶子葯喂給了第6號老鼠  和7號老鼠
 99 第97瓶子葯喂給了第1號老鼠  和6號老鼠  和7號老鼠
100 第98瓶子葯喂給了第2號老鼠  和6號老鼠  和7號老鼠
101 第99瓶子葯喂給了第1號老鼠  和2號老鼠  和6號老鼠  和7號老鼠
102 所有瓶子都測試過了
103 所有瓶子都測試過了
104 所有瓶子都測試過了
105 所有瓶子都測試過了
106 所有瓶子都測試過了
107 所有瓶子都測試過了
108 所有瓶子都測試過了
109 所有瓶子都測試過了
110 所有瓶子都測試過了
111 所有瓶子都測試過了
112 所有瓶子都測試過了
113 所有瓶子都測試過了
114 所有瓶子都測試過了
115 所有瓶子都測試過了
116 所有瓶子都測試過了
117 所有瓶子都測試過了
118 所有瓶子都測試過了
119 所有瓶子都測試過了
120 所有瓶子都測試過了
121 所有瓶子都測試過了
122 所有瓶子都測試過了
123 所有瓶子都測試過了
124 所有瓶子都測試過了
125 所有瓶子都測試過了
126 所有瓶子都測試過了
127 所有瓶子都測試過了
128 所有瓶子都測試過了
129 所有瓶子都測試過了
130 經老鼠檢測,有毒的瓶子為:88
輸出結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM