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.

分析:

本题可以这么考虑问题, 先是二维地排列罐子, 然后分别让两头猪去尝试找出哪一行和哪一列有毒.间隔时间为15分钟, 由于测试时间是60分钟 所以总共1只猪能测试5行或者5列. (这里不是4行或者4列, 因为如果前面4个测试猪都没死的话, 说明最后一行/最后一列肯定有毒). 总结一下,1个维度交给1只猪,  能帮我们检查出(测试时间/毒发时间 + 1)个维度单位.

那么回到二维的例子里面, 2只猪能帮我们检查5*5=25个罐子,那么如果是三维, 就是5^3 = 125个, 以此类推随着维度的上升,只要最后的水桶数大于我们需要检查的水桶数,就需要几头猪.

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

所以 ,  pigs = ceil(log_5(1000)) = 5 pigs

代码比较简单主要是思路分析:

class Solution {
public:
    int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
        int tests=(minutesToTest/minutesToDie)+1;
        int pigs=0;
        while(pow(tests,pigs)<buckets)
       { pigs++;}
       return pigs;
    }
};


还有一种思路如下:

Eg. 4 buckets, 15 mins to die, and 15 mins to test.

The answer is 2. Suppose we use A and B to represent pigs, we could have

Obviously we could use the binary form to represent the solution.

Conclusion: If we have x pigs, we could use them to represent (encode) 2^x buckets.

2. What if we could have more than one attempts?

Eg. 4 buckets, 15 mins to die, and 30 mins to test.

At the moment, I consider the problem as an encoding problem: With more attempts, how to use fewer pigs to represent all the buckets?

I got lost at this step by keep thinking the binary way. After hanging around the forum, I got the idea to change my views. Let's go back to the one shot situation. What does the binary form mean? It's much easier if we regard it as:

  • 0 means the pig does not drink and die.
  • 1 means the pig drinks in the first (and only) round.

We could generalise with:

  • 0 means the pig does not drink and die.
  • 1 means the pig drinks in the first round and die.
  • 2 means the pig drinks in the second round and die.
    ...
  • t means the pig drinks in the t-th round and die.

Conclusion: If we have t attempts, we could use t+1-based number to represent (encode) the buckets. (That's also why the first conclusion uses the 2-based number)

EXAMPLE

Eg. 8 buckets, 15 mins to die, and 40 mins to test.

We have 2 (= (40/15).floor) attempts, as a result we'll use 3-based number to encode the buckets.

How many pigs do we need? Answer is 2 (= Math.log(8, 3).ceil)

For example 3-based number 02 means: the pig A does not drink and die, and the pig B drinks in the second round and die.


参考资料:

https://discuss.leetcode.com/topic/67666/another-explanation-and-solution

https://discuss.leetcode.com/topic/67482/solution-with-detailed-explanation/2