458. 可怜的小猪
有1000只水桶,其中有且只有一桶装的含有毒药,其余装的都是水。它们从外观看起来都一样。如果小猪喝了毒药,它会在15分钟内死去。
问题来了,如果需要你在一小时内,弄清楚哪只水桶含有毒药,你最少需要多少只猪?
回答这个问题,并为下列的进阶问题编写一个通用算法。
进阶:
假设有 n 只水桶,猪饮水中毒后会在 m 分钟内死亡,你需要多少猪(x)就能在 p 分钟内找出“有毒”水桶?n只水桶里有且仅有一只有毒的桶。
分析: x只猪喝水来找毒药,最优的方法应该是把x只猪看出x维,每只猪喝该维为某值的桶。这样每过m分钟,最外一层水桶就能判断出是否有毒,而且剩下的时间足够判断内部具体哪个桶有毒。
由于前4桶无毒,那么最后一桶肯定有毒,所以一只猪可以鉴别5桶水。
以二维为例,小猪编号(0,1),水桶编号(00,01,02,…,10,11,…,43,44)共25桶,每15分钟死一次,说明一小时可以喝四桶水,鉴别五桶水。第一次,小猪0喝第0位为0的,小猪1喝第1位为0的,以此类推。
15min:
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
0 | 1 | 1 | 1 | 1 | 1 |
1 | 1 | 0 | 0 | 0 | 0 |
2 | 1 | 0 | 0 | 0 | 0 |
3 | 1 | 0 | 0 | 0 | 0 |
4 | 1 | 0 | 0 | 0 | 0 |
30min:
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
0 | 1 | 1 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 0 | 0 | 0 |
3 | 1 | 1 | 0 | 0 | 0 |
4 | 1 | 1 | 0 | 0 | 0 |
45min:
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
0 | 1 | 1 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 1 | 1 | 1 |
3 | 1 | 1 | 1 | 0 | 0 |
4 | 1 | 1 | 1 | 0 | 0 |
60min:
0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
0 | 1 | 1 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 1 | 1 | 1 |
3 | 1 | 1 | 1 | 1 | 1 |
4 | 1 | 1 | 1 | 1 | 0 |
结果相当于求minutesToTest/minutesToDie+1
为基数的最少能用多少位来表达buckets
。
class Solution {
public:
int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
if(buckets==1) return 0;
int res=1;
int base = minutesToTest/minutesToDie+1;
for(int i=1;;i++)
{
res*=base;
if(res>=buckets) return i;
}
return 0;
}
};