邏輯思考題
對於一個優秀的程序員來說,學習理解一些邏輯思考題有助於開闊自己的思維,在編碼過程中邏輯更加的嚴密完整。同時,還能增添日常枯燥生活的趣味,通過解答一道復雜的邏輯思考題,會獲得慢慢的成就感,那我們還有什么理由不去學習和理解呢?
1. 囚犯問題
有100個囚犯,將他們站成一排依次報數,報到奇數的那個人被槍斃,接着開始下一輪報數,報到奇數的被槍斃,依次類推,到最后只剩一個人時無罪釋放,假如你現在是一名囚犯,要站在第幾個位置才能活到最后?
思考:100個囚犯,第一次槍斃會少一半也就是50人,第二次槍斃依然是一半,因為剩余人數是偶數,於是依次除2,到最后只剩下一人,一共需要6次槍斃。
問題是知道了槍斃次數,該如何知道最后那個幸運兒是在那個位置呢? 於是我想把問題簡單化一些,換成10個囚犯,這下就簡單多了,通過推演,最后的幸運兒就是第八位的那位囚犯。但我們進行了幾輪槍斃呢?依照上圖算法得出是3輪,3和8有什么關系呢?這時我不由想到剛學的二進制,2的3次方比就是8嗎?難道?是這個規律?我趕緊將囚犯增加到20位,然后依照上圖推算得出需要槍斃4輪,最后的幸運兒是16號,2的4次方剛好是16,所以該題的解決方法就是通過除2的方法算出需要多少輪,最終的幸運位置就是2的n次冪。
盡管得到了解決方法但我依然覺得我對這個方法的原理還是不夠理解,不明白其中的原理究竟是為什么?通過在網上尋找答案,我終於找到了還算合理的解釋,如下:
若將編號換成2進制,偶數是指尾數為0,奇數則為尾數為1。第一輪將奇數全數槍斃後,剩下人再下一輪的編號即為目前編號除以2(例:2號變1號、4號變2號),而在2進制除以2的意義即為去掉尾數的0。故能夠存活的人在2進制的編號為1000000,即為第64個人
正解:首先我們將囚犯總數換算成二進制來進行理解,奇數位槍斃即二進制最低位為1的數被槍斃,比如(二進制101,二進制111...),而那些沒有被槍斃的犯人,由於經過上一輪的槍斃,他們的位置發生了改變,原本在2位置的范圍變成了1位置,4位置的犯人變成了2位置,他們的位置都在原先的位置上除了2,在二進制中對偶數除2就是去0(去除最右邊的0),所以要想要活得久,就必須這個數的1位置離右邊越遠越好,比如1000000,所以在100個人中,換算為二進制即為1100100人中,1位置最遠離右邊的一個數就是1000000這個數,換算為10進制就是64。
2. 老鼠毒葯問題
有99瓶水和一瓶毒葯,需要至少多少只老鼠才能知道這100瓶液體中瓶是毒葯?(提示:一只老鼠可以喝多瓶液體)
思考:如果是一只老鼠喝一瓶那就需要100只才能試出來了,顯然這不是最優解。因為老鼠吃了毒葯只有死和活兩種可能,所以我們可以考慮用二進制來解決,用二進制來表示這100瓶液體一共需要7位數,所以答案就在其中了
正解:100瓶液體用二進制編號共需要7位,100的二進制是1100100,我們只需要7只老鼠,從左到右排序,碰到液體編號的二進制位是1就喝,是0就不喝,然后看哪些老鼠死了,然后在看他們共同喝了哪一瓶液體,並且那瓶液體沒被其他老鼠喝,那瓶液體就是毒葯,可能文字表示不是很形象,直接上圖