1. 程式人生 > >python第9周作業——leetcode 458 可憐的小豬

python第9周作業——leetcode 458 可憐的小豬

題目

有1000只水桶,其中有且只有一桶裝的含有毒藥,其餘裝的都是水。它們從外觀看起來都一樣。如果小豬喝了毒藥,它會在15分鐘內死去。
問題來了,如果需要你在一小時內,弄清楚哪隻水桶含有毒藥,你最少需要多少隻豬?
回答這個問題,併為下列的進階問題編寫一個通用演算法。
進階:
假設有 n 只水桶,豬飲水中毒後會在 m 分鐘內死亡,你需要多少豬(x)就能在 p 分鐘內找出“有毒”水桶?n只水桶裡有且僅有一隻有毒的桶。

解題思路

這道題最重要的就是解題思路。
一開始找不到思緒,後來參考了其他人的解題方法,豁然開朗。
其實最關鍵的就是用一個n維空間定義座標的思想。
注意,題目中並沒有說1頭小豬15分鐘內只能喝1桶水。

用題目中給的資料為例:
每隻豬在實驗時間內可檢測的數量是60/15+1=5(需要注意的是最後要+1,因為如果前面的水喝完都沒死的話,說明毒水肯定是最後一桶,也不用再喝了)。
如果用兩頭小豬進行實驗,則可將水桶定義為二維座標,兩頭豬分別檢測x與y方向的水:每頭豬15分鐘內需嘗試5桶水(一排或一列)。
以此類推,3頭豬則可推廣到3維座標,對應的,每頭小豬每15分鐘內嘗試5^2桶水。
這樣,每增加1頭小豬,可檢測的水桶數就乘5,問題解決效率就很高了。
理清了思路,程式碼其實很簡單。

程式碼

class Solution(object):
    def poorPigs(self, buckets, minutesToDie, minutesToTest)
:
""" :type buckets: int :type minutesToDie: int :type minutesToTest: int :rtype: int """ times = minutesToTest / minutesToDie + 1 #每頭豬最多可測試的水桶數 num = 0 while pow(times,num) < buckets: num = num + 1 return
num

題外話(皮一下)

高效率總是要犧牲其他方面的代價的。從動物福利與保護的角度來講,本題採用上述方法一方面減少了實驗動物的數量,但另一方面也增加了實驗動物的死亡概率。很大概率上,採用n只小豬進行實驗,最後它們都會中毒而亡,因為採用n維座標定位需要n個元素。而採用線性搜尋的話測出毒水只用犧牲1頭豬。這大概也就是題目為什麼是“可憐的小豬”的原因了吧,因為從它們被選定成為實驗豬起,就面臨九死一生的危險境地。