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

最后,这些猪真的是好惨啊= =






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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值