458.可怜的小猪

458.可怜的小猪

题目

有 buckets 桶液体,其中 正好 有一桶含有毒药,其余装的都是水。它们从外观看起来都一样。为了弄清楚哪只水桶含有毒药,你可以喂一些猪喝,通过观察猪是否会死进行判断。不幸的是,你只有 minutesToTest 分钟时间来确定哪桶液体是有毒的。

喂猪的规则如下:

选择若干活猪进行喂养
可以允许小猪同时饮用任意数量的桶中的水,并且该过程不需要时间。
小猪喝完水后,必须有 minutesToDie 分钟的冷却时间。在这段时间里,你只能观察,而不允许继续喂猪。
过了 minutesToDie 分钟后,所有喝到毒药的猪都会死去,其他所有猪都会活下来。
重复这一过程,直到时间用完。
给你桶的数目 buckets ,minutesToDie 和 minutesToTest ,返回在规定时间内判断哪个桶有毒所需的 最小 猪数。

示例 1:

输入:buckets = 1000, minutesToDie = 15, minutesToTest = 60
输出:5

示例 2:

输入:buckets = 4, minutesToDie = 15, minutesToTest = 15
输出:2

示例 3:

输入:buckets = 4, minutesToDie = 15, minutesToTest = 30
输出:2

提示:

1 <= buckets <= 1000
1 <= minutesToDie <= minutesToTest <= 100

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/poor-pigs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

思考

这道题是读懂了,一个猪可以喝任意桶的水,但是看示例的时候发现自己好像又没懂,想不出来这个答案。

以示例2为例,我开始想的一个猪喝一桶,需要3个猪,哪个猪死了,哪桶就有毒,如果都没死那就是剩下的有毒。答案说的是2,那不是2个猪各喝两桶?那怎么判断喝的两个里面哪一个是啊?
后面想了想,难道一桶水可被好几个猪喝吗?
根据时间,一个猪能喝的次数=minutesToTest/minutesToDie,那么这里的猪只能喝1次。根据答案来看,一个猪喝2桶,4/桶数 = 猪的个数,这个我们就用猪的个数倒推理解以下题。

知道了一桶水可以被好几个猪喝之后,好像有了一点思路。

image

上图我们是根据最少的猪数倒推的,现在我们要求猪的个数。根据刚刚画图,这里可以转换一个思路:需要多少猪可以把桶区分出来

用最小单位表示最大信息量,这里想到了二进制
每个猪有两个状态,0表示活,1表示死,假设只有一次机会,我们可以根据图得出:
4桶可以用二级制表示,00(都活)、01(1号猪死了)、10(2号猪死了)、11(都死了)。
9桶用二进制表示至少需要4个猪,也就是需要4位二级制就能区别出。

假设有2次机会呢?这里需要多考虑一轮,我就推不出来了。

别人的解法

思路一

举例说明:

假设:总时间 minutesToTest = 60,死亡时间 minutesToDie = 15,pow(x, y) 表示 x 的 y 次方,ceil(x)表示 x 向上取整
当前有 1 只小猪,最多可以喝 times = minutesToTest / minutesToDie = 4 次水
最多可以喝 4 次水,能够携带 base = times + 1 = 5 个的信息量,也就是(便于理解从 0 开始):
(1) 喝 0 号死去,0 号桶水有毒
(2) 喝 1 号死去,1 号桶水有毒
(3) 喝 2 号死去,2 号桶水有毒
(4) 喝 3 号死去,3 号桶水有毒
(5) 喝了上述所有水依然活蹦乱跳,4 号桶水有毒
结论是 1 只小猪最多能够验证 5 桶水中哪只水桶含有毒药,当 buckets ≤ 5 时,answer = 1

那么 2 只小猪可以验证的范围最多到多少呢?我们把每只小猪携带的信息量看成是 base进制数,22 只小猪的信息量就是 pow(base, 2) = pow(5, 2) = 25,所以当 5 ≤ buckets ≤ 25时,anwser = 2

那么可以得到公式关系:pow(base, ans) ≥ buckets,取对数后即为:ans ≥ log(buckets) / log(base),因为 ans 为整数,所以 ans = ceil(log(buckets) / log(base))

作者:guanpengchn
链接:https://leetcode-cn.com/problems/poor-pigs/solution/hua-jie-suan-fa-458-ke-lian-de-xiao-zhu-by-guanpen/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

根本想不到呜呜呜
一只猪5个信息,两只猪5的平方次...

class Solution {
    public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
        int times = minutesToTest / minutesToDie;
        int base = times + 1;
        int ans = (int)Math.ceil(Math.log(buckets) / Math.log(base));
        return ans;
    }
}


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

思路二

这个题解是我之前想法的接续。终于想明白了这种解法,呜呜呜他好厉害!!

image

https://leetcode-cn.com/problems/poor-pigs/solution/tong-ge-lai-shua-ti-la-k-jin-zhi-wen-ti-ha2ze/

posted @ 2021-11-25 22:17  rananie  阅读(31)  评论(0)    收藏  举报