458. 可怜的小猪

1、458. 可怜的小猪

有 1000 只水桶,其中有且只有一桶装的含有毒药,其余装的都是水。它们从外观看起来都一样。如果小猪喝了毒药,它会在 15 分钟内死去。

问题来了,如果需要你在一小时内,弄清楚哪只水桶含有毒药,你最少需要多少只猪?

回答这个问题,并为下列的进阶问题编写一个通用算法。

进阶:

假设有 n 只水桶,猪饮水中毒后会在 m 分钟内死亡,你需要多少猪(x)就能在 p 分钟内找出 “有毒” 水桶?这 n 只水桶里有且仅有一只有毒的桶。

提示:

  • 可以允许小猪同时饮用任意数量的桶中的水,并且该过程不需要时间。
  • 小猪喝完水后,必须有 m 分钟的冷却时间。在这段时间里,只允许观察,而不允许继续饮水。
  • 任何给定的桶都可以无限次采样(无限数量的猪)。

解释:

这里说明一下如何使用两头猪检测25桶水。


第一步:对这25瓶液体使用5进制编码,如下。你也可以看成一个[x,y]的二维坐标。

pig1

40 41 42 43 44

30 31 32 33 34

20 21 22 23 24 pig2

10 11 12 13 14

00 01 02 03 04


第二步:开始喝液体(两只猪分别按行、列开喝)

第一只猪,在第0min钟,把第一列[40 30 20 10 00]这5桶水全喝了。结果被毒死了(<15min见效)。第一只猪不能再喝了。

第二只猪,在第0min钟,把第一行[00 01 02 03 04]这5桶水全喝了,什么事都没有…

第15min钟,继续喝第二行[10 11 12 13 14]…

第30min钟,继续喝第三行[20 21 22 23 24]这五桶水全喝了,结果被毒死了。


第三步:那么,有毒的液体就是编码为20的那瓶。


总结,一只猪每15min钟都有一个死活状态。0min 15min 30min 45min 60min。而我们,通过他们的死亡时间,推断出有毒液体。

可怜的小猪。没有幸存者。

是的,最终,这两只猪都死了…

代码:

方法1:

//458. 可怜的小猪
    public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
        int times = minutesToTest / minutesToDie + 1;
        //Math.log(n):求以e为低,n的对数
        //Math.log(buckets) / Math.log(times):求以times为低,buckets的对数
        int count = (int) Math.ceil(Math.log(buckets) / Math.log(times));
        return count;
    }

方法2:

  /*
    times = test/die +1 ; 将木桶编号转化成times(5)进制的数, 每个小猪去确定一位数,规定时间内可以喝 test/die(4) 次, 如果最终没死,说明该位取该进制下最大的数(4); 形象化描述的话,就是建立具有小猪个数(x)维度的坐标系.
    */
    public int poorPigs2(int buckets, int minutesToDie, int minutesToTest) {
        int times = minutesToTest / minutesToDie + 1;
        int i = 0;
        int number = 1;
        while (number < buckets) {
            number *= times;
            i++;
        }
        return i;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值