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.
int poorPigs(int buckets, int minutesToDie, int minutesToTest)
1、这其实是一道数学题,想明白了代码不超过两行。我不会说我连前面的1000个桶这道具体的题目都做错的……直到看见答案才明白过来。
2、具体数字的题目,答案是5,不是8、也不是23、更不是250。具体解法如下:
假设有25个桶,我们只需要两只猪。把25个桶放成5行5列,如下形状:每个×代表一个水桶。
0min | 15min | 30min | 45min | 60min | |
---|---|---|---|---|---|
0min | × | × | × | × | × |
15min | × | × | × | × | × |
30min | × | × | × | × | × |
45min | × | × | × | × | × |
60min | × | × | × | × | × |
第一只猪在0min喝下第一行的水,在15min喝下第二行的水,在30min喝下第三行的水,在45min喝下第四行的水。如果45min喝下60min出结果的时候,猪还没say goodbye的话,那么毒必定在最后一行。
与此同时,第二只猪在0min喝下第一列的水,15min喝下第二列的水……类推。如果45min喝下60min出结果的时候,猪还在,那说明毒在最后一列。结合第一只猪的结果,说明毒在最后一行最后一列。
我们可以看出,一只猪可以判断一个维度的信息,两只猪可以决定两个维度的信息,也就是5^2=25个水桶的情况可以由两只猪判断得出。
所以三只猪可以判断5^3=125,四只猪可以判断5^4=625,五只猪可以判断5^5>1000个水桶的情况。
3、所以放到通用的题目里面,n个待判定的水桶,限时p分钟,m分钟出一次结果,这道题结果就是ceil(log(p/m+1)n),ceil是取上限函数。
代码如下:
int poorPigs(int buckets, int minutesToDie, int minutesToTest)
{
int chances=floor(minutesToTest/minutesToDie);
return ceil(log10(buckets)/log10(chances+1));//变换一下底数,以10为底,结果一样
}
上述代码实测2ms,beats 100% of cpp submissions。大家做的都一样。