1. 程式人生 > >458. Poor Pigs(python+cpp)

458. Poor Pigs(python+cpp)

題目:

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.

解釋: 2^10=1024>1000(這是用二進位制法測試毒藥的題,小老鼠喝毒藥,和這道題的思路是不一樣的~) 老鼠喝毒藥:

有100只一模一樣的瓶子,編號1-100。其中99瓶是水,一瓶是看起來像水的毒藥。只要老鼠喝下一小口毒藥,一天後則死亡。現在,你有7只老鼠和一天的時間,如何檢驗出哪個號碼瓶子裡是毒藥?
解決此題的方法可謂二進位制應用的經典:
首先,將瓶子的10進位制編號數改成7位的2進位制碼。然後,讓第1只老鼠喝所有2進位制碼第1位
是1的瓶子中的水;讓第2只老鼠喝所有2進位制碼第2位是1的瓶子中的水;以此類推下去。這
樣,每個老鼠第二天的死活情況就決定了毒水瓶子二進位制碼這一位的數字:老鼠死,對應1
,反之為0。換言之,將7只老鼠死活情況排成一排。比如說結果是“死活死死活活死”的話,
毒水瓶子的二進位制標籤就是:1011001,轉換成10進位制,得到89。

為什麼可憐不言而喻…本題可以這麼考慮問題, 先是二維地排列罐子, 然後分別讓兩頭豬去嘗試找出哪一行和哪一列有毒.間隔時間為15分鐘, 由於測試時間是60分鐘 所以總共1只豬能測試5行或者5列. (這裡不是4行或者4列, 因為如果前面4個測試豬都沒死的話, 說明最後一行/最後一列肯定有毒). 總結一下,1個維度交給1只豬, 它鞠躬盡瘁死而後已, 能幫我們檢查出(測試時間/毒發時間 + 1)個維度單位(這裡假設喝水是不需要時間的,喝完一行/列的水以後等15分鐘,如果沒死就繼續測試下一行/列)。 那麼回到二維的例子裡面, 2只豬能幫我們檢查5*5=25個罐子,那麼如果是三維, 就是53 = 125個, 以此類推隨著維度的上升,只要最後的水桶數大於我們需要檢查的水桶數,就需要幾頭豬. 使用一頭豬來找毒水的行數 (讓它喝下桶 1, 2, 3, 4, 5, 裡的水,等15分鐘;讓它喝下桶 6, 7, 8, 9, 10, 裡的水,等15分鐘…)。使用另一頭豬來找毒水的列數 (讓它喝下桶 1, 6, 11, 16, 21, 裡的水,等15分鐘;讓它喝下桶 2, 7, 12, 17, 22, 裡的水,等15分鐘…)。

1  2  3  4  5
6  7  8  9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

使用一頭豬來找毒水的行數 擁有60分鐘,每次毒水測試需要15分鐘,意味著我們可以進行4次測試。從 0min 開始第一波測試,第15min 出 0 的結果並進行第二波測試,第 30min 出15 的結果並進行第三波測試,第 45min 出 30 的結果並進行第4波測試。第 60min 出 45 的結果。如果 行豬 在第三次測試中死亡,那麼毒水就在第3行。如果 列豬 在4次測試中都沒死,那麼毒水在它沒喝的第5列中。(這就是為什麼只能做4波測試,卻能夠測試5行/列)。 如果有3頭豬,可以用 5×5×5 正方體,使用一頭豬來測試一個維度:豬1 從上到下 喝一層層的水,豬2 從左向右 喝,豬3 從前向後 喝。所以三頭豬最多能測試125個桶。 python程式碼:

from math import ceil,log10
class Solution(object):
    def poorPigs(self, buckets, minutesToDie, minutesToTest):
        """
        :type buckets: int
        :type minutesToDie: int
        :type minutesToTest: int
        :rtype: int
        """
        if buckets==1:
            return 0
        return int(ceil(log10(buckets)/log10(minutesToTest/minutesToDie+1)))

c++程式碼:

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

總結: 第一反應是和小老鼠喝毒藥一樣的解法,後來發現不是的。