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)));
    }
};

总结:
第一反应是和小老鼠喝毒药一样的解法,后来发现不是的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值