版權申明:本文為博主窗戶(Colin Cai)原創,歡迎轉帖。如要轉貼,必須注明原文網址 http://www.cnblogs.com/Colin-Cai/p/7726193.html 作者:窗戶 QQ:6679072 E-mail:6679072@qq.com
因為網上這道題沒有詳細思路,我想我還是補個詳細思路。這道題目描述是這樣的:
有12個一模一樣的球,其中11個重量一模一樣,剩下的1個重量和其他的不一樣。使用一個無砝碼的天平稱3次,找出重量不一樣的這一個球,以及知道這個球比其他的球重還是輕。
這個題目似乎很早就出來了,估計有十幾年吧,曾以不一樣的身份出現在各個帖子里,有的時候號稱是微軟筆試題,也曾被稱為google筆試題,還有說是騰訊筆試題的。至於它真實的出處,我們不必在意。另外還有13個球的版本的,只是只要找出球就行了。倒是這道題的詳細解題步驟,這些年來似乎從未看到,於是,今天我就來給個詳細的分析步驟。
雖然用信息論的術語,比如信息墒、信息論下界來描述這個問題會比較規范,不過我想說的更加通俗一點。
我們知道無砝碼的天平每次稱量會有三種結果:兩邊一樣重,左邊重,右邊重。根據組合里的乘法原理,三次天平稱量有27種結果,而題目的目的是要區分12(球的數目)*2(重或輕)=24種不同情況。我們給出的稱法其實是算法,算法運行的過程中只有遇到每一次稱重的不同結果,才會面臨着不同的分支,從而計算出不同的結果。於是,我們每一種稱量結果,會對應着不同的情況。總共最多有27種稱量結果,而只有24種情況需要分辨,如果把這27種稱量結果看成編碼,把24種情況看成需要分辨的不同信息,那么顯然,編碼數量是足夠的。也就是,是有可能的。這種方法可以用來排除結果,卻不可以用來肯定結果,也可以用於過程中,比如過程中對於整個三個稱重還剩下n次稱重,而需要區分的情況為m種,如果m>3n,也就是編碼不夠用了,那么表示剛才的稱重方法是得到結果,應該被排除。
任何一次稱重,如果兩邊小球數量不一樣多,而如果稱出小球少的一方輕於小球多的一方,則無法減少要區分的情況,所以會白白浪費一次稱重。從而,每一次稱重,左右都是相同的球。
好,准備的差不多了,我們可以開始推算法了,我們給12個球先編號,從1編到12。
我們先看第一次稱重左右各多少個球,如果左右各1~3個球,剩下的球大於多於6個,如果第一次稱重為左右一樣重,那么要區分的情況大於等於2*6=12種,而剩余的2次稱量只能區分9種情況,所以不行;如果左右的球為5~6個,那么如果第一次稱重兩邊不一樣種,那么要區分的情況就是10或12種(要么是重的那邊有一個球重了,要么是輕的那邊有一個球輕了,參與稱重的所有球都有可能是要找的球),也無法用剩余的2次稱重區分所有的情況。所以,第一次稱重只能是左右都是4個球。
不失一般性,第一次稱重左邊選擇編號1、2、3、4,右邊選擇編號5、6、7、8。
第一次稱重會有三種可能:
左右一樣重;
左邊重於右邊;
右邊重於左邊。
前兩種情況是對稱的,只要考慮左邊重於右邊就可以了,從而只需要考慮左右一樣重、左邊重於右邊這兩種情況即可。
(一)
先考慮左右一樣重,那么要找的球在9、10、11、12中,也就是還存在8種情況。考慮第二次稱量。
如果9、10、11、12都在這一次稱量上,那么天平不會平衡,那么兩次稱量總共有2*3=6種結果(2為重、輕),無法區分8種情況。
如果第二次稱量中9、10、11、12中有2個或2個以上的球未參與稱量,那么天平一旦平衡,這些未參與稱量的球將有至少4種情況需要通過最后一次稱量來決定,那么也是不可能的。
所以,第二次稱量中,9、10、11、12有3個球參與稱量,不失一般性,就選9、10、11三個球,9、10、11三個球和1、2、3三個不是目標的球做第二次稱重(其實還有一種稱法,就是9、10和11、1稱,也一樣可以分辨出來,這里不討論)。分三種情況:
(1) 9、10、11重於1、2、3,那么只有三種可能:9重,10重,11重。第三次稱量就拿9和10來比較,如果9重於10,結果就是9重;如果10重於9,結果就是10重;如果9、10一樣種,結果就是11重。
(2) 9、10、11輕於1、2、3,和上面道理一樣。
(3) 9、10、11和1、2、3一樣重,那么要找的球就是12。最后一次稱量就用12比上任何一個正常的球就知道12是重了還是輕了。
(二)
再考慮1、2、3、4重於5、6、7、8,那么結果會有8種可能:1重,2重,3重,4重,5輕,6輕,7輕,8輕。8個球都有可能,那么最后一次稱重至少要有5個球參與,以防第二次稱平之后有超過3種情況,從而最后一次稱不出來。我們選擇1、2、5和3、6、9稱第二次。如果1、2、5重於3、6、9,那么有1重,2重,6輕三種情況;如果1、2、5輕於3、6、9,那么有5輕,3重兩種情況;如果1、2、5和3、6、9一樣重,那么有4重,7輕,8輕三種情況。
兩重一輕、兩輕一重(其實就是前一種反過來,所以只用考慮前一種)很容易一次稱出,把兩個認為可能重的比較一下重量,如果不平衡,那么重的那個就是要找的球;如果平衡,就是剩下的那一個球。一輕一重就更容易了,拿一個正常的球和其中一個球來比就行了。
從而,問題就這么解決了。其實題目可以再變一下,12個球變成13個球,不過三次稱重只可以保證找出不一樣的那個球,卻未必知道這個球是重還是輕。我們可以分析一下,首先,每次左右球數目都一樣,道理同上。第一次選擇的球只能是左右都4個,如果是左右大於等於5個,萬一不平衡,就有最少10種情況(參與稱重的球都有可能),那么2次稱重是分辨不出來10種情況,而如果是左右3個以內,於是面臨2次稱重分辨至少7個不知輕重的球,7>3+3,2次搞不定。第一次稱重如果不平衡,那么和上面12個第一稱不平衡一樣,可以解決。如果平衡,那么就面臨着2次稱重在5個球中找。如果第二稱重有這5個球中4個或4個以上的球參與,那么萬一不平衡,那么需要一次稱重分辨至少4種情況,不可能解決。如果第二稱最多只有2個球參與,那么萬一平衡,那么剩余的球(至少3個)需要一次稱重稱出,這是不可能的。所以第二稱有其中3個球參與,左邊2個,右邊剩下的1個和從剛才8個球中找一個正常的。但萬一平衡,意味着還有一次稱重要分辨2個球,這種情況下,是存在只知道球不知道輕重的可能,因為2*2>3。