[LeetCode] Poor Pigs

There are 1000 buckets, one and only one of them contains poison, the rest are filled with water. They all look the same. If a pig drinks that poison it will die within 15 minutes. What is the minimum amount of pigs you need to figure out which bucket contains the poison within one hour.

Answer this question, and write an algorithm for the follow-up general case.

Follow-up:

If there are n buckets and a pig drinking poison will die within m minutes, how many pigs (x) you need to figure out the "poison" bucket within p minutes? There is exact one bucket with poison.


題意看起來並不複雜,但是思考這個問題很容易陷入誤區。比如一開始,我就陷入了二分的思路,而且很難跳出來。(這讓我想起之前做的一道測試雞蛋硬度的思維題)後來發現這題用二分得到的顯然不是minimum,卻又不知道究竟應該如何取得最小值。在查找了各種大牛的博客後纔得到了答案。仔細想來這個思路也是很巧妙。特此記錄一下。

思路:首先我們看看例子,1000桶水,死亡時間15mins,測試時間1小時。至少需要多少頭豬才能找到有毒的水桶呢?

我們用這樣的方法進行測試:一開始將1號桶的水餵給它,如果15分鐘後它沒死,則將2號桶的水餵給它,以此類推...

這樣我們在60mins裏有進行四次實驗的機會,所以對於一頭豬而言,它應有5種狀態:

  • 第一次實驗後死亡
  • 第一次實驗後存活,第二次實驗後死亡
  • 第二次實驗後存活,第三次實驗後死亡
  • 第三次實驗後存活,第四次實驗後死亡
  • 活到最後

假設要測試5桶水(編號分別爲1,2,3,4,5),那麼只需一頭豬就可以判斷哪桶水有毒。

  • 豬在第一次實驗後死亡(第15min時死亡)說明1號桶的水有毒
  • 豬在第二次實驗後死亡(第30min時死亡)說明2號桶的水有毒
  • 豬在第三次實驗後死亡(第45min時死亡)說明3號桶的水有毒
  • 豬在第四次實驗後死亡(第60min時死亡)說明4號桶的水有毒
  • 豬在活到最後說明5號桶的水有毒

假設要測試25桶水(編號分別爲01,02,03,...,24,25),那麼只需兩頭豬就可以判斷哪桶水有毒。怎麼做呢?

爲了方便說明,我們首先將25桶水按照如下順序排列好:

A   B   C   D   E

a 01 02 03 04 05

b 06 07 08 09 10

c 11 12 13 14 15

d 16 17 18 19 20

e 21 22 23 24 25

然後我們同時做兩件事:

1.將a行(01,02,03,04,05)的水取出混合餵給第一頭豬,如果15分鐘後它沒死,則將b行(06,07,08,09,10)的水餵給它,以此類推...

  • 豬在第一次實驗後死亡(第15min時死亡)說明a行的水有毒
  • 豬在第二次實驗後死亡(第30min時死亡)說明b行的水有毒
  • 豬在第三次實驗後死亡(第45min時死亡)說明c行的水有毒
  • 豬在第四次實驗後死亡(第60min時死亡)說明d行的水有毒
  • 豬在活到最後說明e行的水有毒
2.將A列(01,06,11,16,21)的水取出混合餵給第一頭豬,如果15分鐘後它沒死,則將B列(02,07,12,17,22)的水餵給它,以此類推...

  • 豬在第一次實驗後死亡(第15min時死亡)說明A列的水有毒
  • 豬在第二次實驗後死亡(第30min時死亡)說明B列的水有毒
  • 豬在第三次實驗後死亡(第45min時死亡)說明C列的水有毒
  • 豬在第四次實驗後死亡(第60min時死亡)說明D列的水有毒
  • 豬在活到最後說明E列的水有毒

然後就可以根據結果推斷這桶水具體在哪一行哪一列了。比如第一隻豬在45min時死亡,第二隻豬在15min死亡,就可以得出第11桶水有毒。

思考到這裏,問題已經基本解決了。我們很容易就能想到,對於125桶水,我們用三隻豬就可以得出結果了。

對於(60/15+1)=5的每一個維度,我們都可以用一隻豬檢測出有毒水桶在這個維度的位置。

回到題目中的通用情況,給出水桶數(buckets), 中毒後死亡時間(minutesToDie), 檢測的總時間(minutesToTest),我們可以根據以上思路寫出代碼:

class Solution {
public:
    int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
        return (int)ceil(log(buckets)/log(minutesToTest/minutesToDie+1));
    }
};

最後,這些豬真的是好慘啊= =






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章