458. 可怜的小猪(Java)

458. 可怜的小猪

问题描述:


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

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

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

进阶:

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


问题解析:
举个例子简化题目意思:

假设我们有 2 头猪,毒需要15分钟才能杀死猪,我们总共有60分钟。那么,用下列方式,我们能至多从25个桶中找到毒水。 把桶放置成 5×5 的方形:

 1  2  3  4  5
 6  7  8  9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

使用一头猪来找毒水的行数 (让它喝下桶 1, 2, 3, 4, 5, 里的水,等15分钟;让它喝下桶 6, 7, 8, 9, 10, 里的水,等15分钟…)。使用另一头猪来找毒水的列数 (让它喝下桶 1, 6, 11, 16, 21, 里的水,等15分钟;让它喝下桶 2, 7, 12, 17, 22, 里的水,等15分钟…)。每一个pig测一维,然后利用行列相交就可以找出有毒的桶。

拥有60分钟,每次毒水测试需要15分钟,意味着我们可以进行4次测试。从 0min 开始第一波测试,第15min 出 0 的结果并进行第二波测试,第 30min 出15 的结果并进行第三波测试,第 45min 出 30 的结果并进行第4波测试。第 60min 出 45 的结果。如果 行猪 在第三次测试中死亡,那么毒水就在第3行。如果 列猪 在4次测试中都没死,那么毒水在它没喝的第5列中。(这就是为什么只能做4波测试,却能够测试5行/列)。

如果有3头猪,可以用 5×5×5 正方体,使用一头猪来测试一个维度:猪1 从上到下 喝一层层的水,猪2 从左向右 喝,猪3 从前向后 喝。所以三头猪最多能测试125个桶。

总的来说, 用这种方式,我们能测试 (⌊minutesToTest / minutesToDie⌋ + 1)pigs 个桶。

    public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {		
    	// 如果只有一个bucket,那里面必然是毒药,不需要pig
        if (buckets == 1) {
            return 0;
        }
        int length = minutesToTest / minutesToDie + 1;
        // 如果buckets大于1的话,pigNum至少为1
        int pigNum = 1; 
        int total = length;  // 可以计算桶的最大个数
        while (total < buckets) {
            pigNum++;
            total *= length;
        }
        return pigNum;
    }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值