题目
有1000个桶,有且仅有一个桶里面装了毒药,其他的都装了水。这些桶从外面看上去完全相同。如果一只猪喝了毒药,它将在15分钟内死去。在一个小时内,至少需要多少只猪才能判断出哪一个桶里装的是毒药呢?
代码
/***
* @param buckets 桶的数量
* @param minutesToDie 毒药发作时间
* @param minutesToTest 最短测试时间
* @return
*/
public static int getPigs(int buckets ,int minutesToDie ,int minutesToTest){
//如果只有一桶水,那么就可以直接确定了
if(buckets <2){
return 0;
}
int dimension = minutesToTest / minutesToDie + 1; //维度
int pig = 0;
int res = 1;
//buckets至少是2,因此一定进入循环,因此pig一定不会是0
while(res<buckets){
res = res * dimension; //每增加一头猪,则以维度的倍数增加可以测试的水桶
pig++;
}
return pig;
}
解题逻辑
思路:
以下思路是看过解析的…
首先根据题目的要求是我们至少需要多少只猪,那么我们假定一只猪的情况下,可以测试多少水桶呢?
一只猪在一个小时内最多可以测试四次,每隔15分钟测一次。那么就有五种状态:15分钟后死,30分钟后死亡,45分钟后死亡,60分钟后死亡,还有一种就是没有死亡。那么一只猪的情况下就可以测试五桶水(在假定只有五桶水的情况下,最后一桶是可以不用测的,既然前面四桶都是安全的,那么最后一桶肯定是有毒的)。
一只猪的情况下已经知道了,如果还没看出规律,那就看看两只猪的情况:这个时候需要借助一些东西了,比如二维数组,二维矩阵,平面直角坐标系等二维的东西来表示。下面看一个图
00 01 02 03 04
10 11 12 13 14
20 21 22 23 24
30 31 32 33 34
40 41 42 43 44
一个二维矩阵,下面就看一下怎么理解:
第一次 第一只猪喝第一行的,第二只猪喝第一列的,那么如果毒药在第一个(00),那么两只猪15分钟后都死亡。如果第一只猪死亡,那么毒药就在第一行。第二只猪的情况同理。
第二次 第一只猪喝第二行,第二只猪喝第二列(这里是毒药不在第一行和第二列的情况下),情况分析参考第一次喝水;假设第一支猪已经死亡,那么第二只猪这次也死亡,那么就在第一行第二列。就这么分析
第三次…
第四次 如果两只猪都没有死亡,那么就是最后一个有毒了(44)
最后说明一下:第一次喝水是在0分钟,第二次喝水是15分钟,第三次喝水时30分钟,第四次喝水是45分钟。
规律大概出来了,一只猪可以测5桶水,两只猪可以测25桶水,随着猪的数量的递增,就将可测试数量乘以五;规律就是五的次幂的运用,或者说可以把每一只猪看成是一位五进制数。那么为什么是五进制或者说是五的倍数呢,这个就对应猪的状态了,猪可以有的状态刚好就是五种,假设猪的状态只有两种,那么就是2的倍数了。
ok,那么看看三只猪的情况 两只猪是二维,那么三只猪就是三维,可以理解为000 0001 … 那么当成五进制来看,那就是可以测125(5 * 5 * 5)次了,要是想具体一点,可以参考空间直角坐标系,就是一个长为1的正方体。
有点啰嗦,并且没有动图…