算法(可怜的小猪)

Posted cjjjj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法(可怜的小猪)相关的知识,希望对你有一定的参考价值。

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

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

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

 

进阶:

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

 

提示:

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

思路:
标签:数学

这道题初看的时候,很多人会纠结:到底需要多少只小猪,而每只小猪又应该具体如何喝水才能判断出哪只水桶有毒药?

这道题最开始不要去关注细节,去想到底应该怎么喂水。而是应该先思考在考察哪方面的问题,数组、链表、二叉树还是数学?那么仔细思考就能得出结论,本质上在考察数学中的 进制 问题。

举例说明:

假设:总时间 minutesToTest = 60,死亡时间 minutesToDie = 15,pow(x, y) 表示 x 的 y 次方,ceil(x)表示 x 向上取整
当前有 11 只小猪,最多可以喝 times = minutesToTest / minutesToDie = 4 次水
最多可以喝 44 次水,能够携带 base = times + 1 = 5 个的信息量,也就是(便于理解从 00 开始):
(1) 喝 00 号死去,00 号桶水有毒
(2) 喝 11 号死去,11 号桶水有毒
(3) 喝 22 号死去,22 号桶水有毒
(4) 喝 33 号死去,33 号桶水有毒
(5) 喝了上述所有水依然活蹦乱跳,44 号桶水有毒
结论是 11 只小猪最多能够验证 55 桶水中哪只水桶含有毒药,当 buckets ≤ 5 时,answer = 1
那么 22 只小猪可以验证的范围最多到多少呢?我们把每只小猪携带的信息量看成是 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))

func poorPigs(buckets int, minutesToDie int, minutesToTest int) int {
    times := minutesToTest/minutesToDie
    times = times + 1
    result := math.Log(float64(buckets))/math.Log(float64(times))
    return int(math.Ceil(result))
}

作者:cao-cao-cao-jiang-jiang
链接:https://leetcode-cn.com/problems/poor-pigs/solution/golang-shi-xian-fang-fa-by-cao-cao-cao-jiang-jiang/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  

以上是关于算法(可怜的小猪)的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 458.可怜的小猪

LeetCode--458--可怜的小猪

LeetCode﹝数学规律ி﹞第N位数字可怜的小猪

系统设计之可怜的小猪

LeetCode 458 可怜的小猪[数学] HERODING的LeetCode之路

LeetCode 458. 可怜的小猪(找毒药问题) / 700. 二叉搜索树中的搜索 / 519. 随机翻转矩阵(哈希表记录交换位置)