小白鼠喝毒水的问题。
??有1000瓶水,其中有一瓶有毒,小白鼠只要嘗一點帶毒的水24小時后就會死亡,至少要多少只小白鼠才能在24小時時鑒別出哪瓶水有毒?
這是一道很經典的面試題目,先說解題方法吧,2^n >= 1000,其中n就是小白鼠的數量。如果知道答案了,也許很多人就恍然大霧,當然有些專業的人士用下面的歸納法證明了下:
1)當n=1時,即有2瓶水,任取一瓶水喂老鼠,若24小時后老鼠死,則此瓶水有毒;若24小時后老鼠沒死,則此瓶水無毒,另一瓶水有毒。課件只需一個老鼠即可判斷出哪瓶有毒。即當n=1時命題成立。
2)假設當n=k(k>1)時,命題為真。即須k只老鼠即可判斷出哪瓶水有毒。
???則當n=k+1時,即有2^(n+1)瓶水。
???將水分成2組,命名為P1和P2,每組2^n瓶水.
???則這兩組瓶中有一組全沒毒,另一組中有僅一瓶有毒。
???a)?取1只老鼠、任取一組瓶子,假設為P1,將P1中的全部瓶子水都讓老鼠嘗一下。則24小時后可以根據此老鼠的生死情況判斷毒藥在哪一組。
???b)?取k只老鼠,根據假設可知當n=k時,可判斷哪瓶水有毒。用這k只老鼠同時去檢測P1和P2,則24小時后可挑出P1中的某一瓶和P2中的某一瓶,這兩瓶可能有毒。
???根據a、b中的結果綜合分析,可得知毒藥瓶是哪一個。
???即當n=k+1時,命題為真。
命題得證。
這個證明應該是沒問題,但是我很感興趣的就是,如何猜出來這個命題的哪?我就說下這個過程吧,來檢測瓶中的水有沒有毒,只能靠小白鼠死沒死亡來判斷,也就是2種狀態,這里1表示死亡,0表示存活。那么10個小白鼠,那么可以表示2^10(代表10次方)中狀態,也就是1024。那么這1024種狀態能不能對應出那瓶水有毒那,如果可以這個題目就解決了。看到這里,又回到了上面的證明,這個歸納法明顯可以證明,此猜想沒問題。由此歸納法可以看出,此問題符合算法中的,動態規劃法,也就是該問題可以分解成更小的問題,1000(也就是1024瓶以內)瓶水給10個老鼠喝,512(512瓶水以內)瓶水給9個老鼠喝...以此類推,平且每個大問題的子問題,還跟這個大問題有關系,由數學歸納法證明的第二步,可以看出,通過子問題的解決,更大的問題帶入到步驟2中就可以解決了。
以上步驟說了半天都是,說明此方法是正確的,可證明的。但是如果要問怎么安排老鼠喝水,才能判斷那瓶有毒那?也就是把這個動態規劃的算法如何來實現。其實改歸納法證明中的第二步驟中的b)后面的內容,已經透露出了運用的實現方法。也就是把有所有的水給某一個老鼠P10喝,剩下的老鼠喝的水都不能包含P10喝的那瓶毒水,那么如果P10死亡了,剩下的都活著,就檢查出來毒水了。以此類推老鼠P9喝的水肯定包含一瓶其他老鼠都沒喝過的,這樣才能檢查出這瓶水有毒。這樣我們就可以得出下面的結論:
1 表示死亡 0 表示存活
0000000001 ? ? ? P1喝了第一瓶的水,其他老鼠都沒喝,那么P1老鼠死亡,其他沒死推斷出第1瓶水有毒
0000000010 ? ? ??P2喝了第二瓶的水,其他老鼠都沒喝,那么P2老鼠死亡,其他沒死推斷出第2瓶水有毒
0000000100 ? ? ??P3喝了第4(2^2)瓶的水,其他老鼠都沒喝,那么P3老鼠死亡,其他沒死推斷出第4(2^2)瓶水有毒
......
這里開始有疑問了,那么從第2---第4瓶水,中間的那瓶水有毒如何推斷那?這里就用到一個方法叫組合。11代表第3瓶水有毒,也就是P1和P2必須同時喝第三瓶水,而P3不能喝,那么P1和P2死,P3沒死就可以得出第三瓶水有毒。下面的各瓶水的判斷,都快可以依據這個理論類推,根據上面數學歸納的證明,應該可以判斷出來所有的剩余的水。這里可以發現一個顯而易見的規律,P1老鼠所有奇數位置的水都得喝,因為P1老鼠可以測試有毒瓶子的位置為xxxxxxxxx1 (x代表未知),換成10進制必須包含一個2^0也就是1,那顯然是奇數。只有這樣才能組合出水的位置,從剛才第三瓶水的判斷也可以看出。P2老鼠喝水當然也有規律了,xxxxxxxx1x,換成10進制必須包含2^1也就是2,根據2進制轉換成10進制的算法,我們看下面的數字4=2^2 , 3=2^1 + 2 ^ 1 , 2 = 2^1 , 1=2^0其中3就包含了2^1方,也就是3號瓶子的水,P2必須喝,根據這個方法5=2^2 + 2^0那么5號p2就不用喝,我們總結下就可以看出,其實P2如果換成10進制的話,每隔2個位置就需要P2喝,也就是6,8,10,12...都需要。那么P3那同理根據這個推算方式,每隔4個位置就需要P3喝,也就是4,8,12...。至此所有的老鼠應該喝的水所在的瓶子的位置都判斷出來了。
上面的方法,講完后,如果你學習過計算機網絡中海明碼的編碼規則,那你豈不是就恍然大悟了。這不就是海明碼的編碼規則么?下面我們就對比下海明碼的編碼規則:
下面看如何計算海明碼(Hamming Code )
海明碼(Hamming Code )編碼的關鍵是使用多余的奇偶校驗位來識別一位錯誤。
碼字(Code Word)?按如下方法構建:
1、把所有2的冪次方的數據位標記為奇偶校驗位(編號為1, 2, 4, 8, 16, 32, 64等的位置)
2、其他數據位用于待編碼數據. (編號為3, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17等的位置)
3、每個奇偶校驗位的值代表了代碼字中部分數據位的奇偶性,其所在位置決定了要校驗和跳過的比特位順序。
位置1:校驗1位,跳過1位,校驗1位,跳過1位(1,3,5,7,9,11,13,15,…) ??這里和老鼠和水的位置是不是一樣的
位置2:校驗2位,跳過2位,校驗2位,跳過2位?(2,3,6,7,10,11,14,15,…)
位置4:校驗4位,跳過4位,校驗4位,跳過4位(4,5,6,7,12,13,14,15,20,21,22,23,…)
位置8:校驗8位,跳過8位,校驗8位,跳過8位(8-15,24-31,40-47,…)
…
如果全部校驗的位置中有奇數個1,把該奇偶校驗位置為1;如果全部校驗的位置中有偶數個1,把該奇偶校驗位置為0.
舉例說明:
一個字節的數據:10011010
構造數據字(Data Word),對應的校驗位留空_ _ 1 _ 0 0 1 _ 1 0 1 0
計算每個校驗位的奇偶性?( ?代表要設置的比特位):
位置1檢查1,3,5,7,9,11:
? _?1?_?0?0?1?_?1?0?1?0.?偶數個1,因此位置1設為0,即: 0 _ 1 _ 0 0 1 _ 1 0 1 0
位置2檢查2,3,6,7,10,11:
0???1?_ 0?0 1?_ 1?0 1?0.?奇數個1,因此位置2設為1,即: 0 1 1 _ 0 0 1 _ 1 0 1 0
位置4檢查4,5,6,7,12:
0 1 1 ??0 0 1?_ 1 0 1?0.?奇數個1,因此位置4設為1,即: 0 1 1 1 0 0 1 _ 1 0 1 0
位置8檢查8,9,10,11,12:
0 1 1 1 0 0 1 ??1 0 1 0.?偶數個1,因此位置8設為0,即: 0 1 1 1 0 0 1 0 1 0 1 0
?
因此碼字為: 011100101010.
?查找并糾錯一位錯誤
上例中構建了一個碼字?011100101010,假定實際接收到的數據是011100101110.?則接收方可以計算出哪一位出錯并對其進行更正。方法就是驗證每一個校驗位。記下所有出錯的校驗位,可以發現校驗位2和8的數據不正確.?錯誤校驗位?2 + 8 = 10,?則位置10的數據出錯。一般說來,對所有校驗位進行檢查,?將所有出錯的校驗位置相加,?得到的就是錯誤信息所在的位置.
至此終于發現原來這個面試題目,使我們學過的。是不是感覺自己學的東西太糙了么?
總結
以上是生活随笔為你收集整理的小白鼠喝毒水的问题。的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机图形学基础-第二章 VB.NET
- 下一篇: c语言 程序延时 校准,c语言实现系统时