458. 可怜的小猪

1、458. 可怜的小猪

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

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

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

进阶:

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

提示:

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

解释:

这里说明一下如何使用两头猪检测25桶水。


第一步:对这25瓶液体使用5进制编码,如下。你也可以看成一个[x,y]的二维坐标。

pig1

40 41 42 43 44

30 31 32 33 34

20 21 22 23 24 pig2

10 11 12 13 14

00 01 02 03 04


第二步:开始喝液体(两只猪分别按行、列开喝)

第一只猪,在第0min钟,把第一列[40 30 20 10 00]这5桶水全喝了。结果被毒死了(<15min见效)。第一只猪不能再喝了。

第二只猪,在第0min钟,把第一行[00 01 02 03 04]这5桶水全喝了,什么事都没有…

第15min钟,继续喝第二行[10 11 12 13 14]…

第30min钟,继续喝第三行[20 21 22 23 24]这五桶水全喝了,结果被毒死了。


第三步:那么,有毒的液体就是编码为20的那瓶。


总结,一只猪每15min钟都有一个死活状态。0min 15min 30min 45min 60min。而我们,通过他们的死亡时间,推断出有毒液体。

可怜的小猪。没有幸存者。

是的,最终,这两只猪都死了…

代码:

方法1:

//458. 可怜的小猪
    public int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
        int times = minutesToTest / minutesToDie + 1;
        //Math.log(n):求以e为低,n的对数
        //Math.log(buckets) / Math.log(times):求以times为低,buckets的对数
        int count = (int) Math.ceil(Math.log(buckets) / Math.log(times));
        return count;
    }

方法2:

  /*
    times = test/die +1 ; 将木桶编号转化成times(5)进制的数, 每个小猪去确定一位数,规定时间内可以喝 test/die(4) 次, 如果最终没死,说明该位取该进制下最大的数(4); 形象化描述的话,就是建立具有小猪个数(x)维度的坐标系.
    */
    public int poorPigs2(int buckets, int minutesToDie, int minutesToTest) {
        int times = minutesToTest / minutesToDie + 1;
        int i = 0;
        int number = 1;
        while (number < buckets) {
            number *= times;
            i++;
        }
        return i;
    }
在Java中创建个简单的智慧养管理系统可以采用面向对象的设计模式,我们可以创建个`Pig`类表示小猪,以及个`PigManagementSystem`类作为系统的入口。这里是个简化的示例: ```java // 定义Pig类 class Pig { private String id; private double weight; // 构造函数、getter和setter方法省略 public void setWeight(double weight) { this.weight = weight; } public double getWeight() { return weight; } } // 管理系统类,包含核心操作方法 class PigManagementSystem { private List<Pig> pigs; public PigManagementSystem() { pigs = new ArrayList<>(); } // 新增小猪 public void addPig(String id, double initialWeight) { Pig pig = new Pig(); pig.setId(id); pig.setWeight(initialWeight); pigs.add(pig); } // 修改小猪重量 public void updatePigWeight(String id, double newWeight) { for (Pig p : pigs) { if (p.getId().equals(id)) { p.setWeight(newWeight); break; } } } // 小猪出栏(删除) public void pigLeaving(String id) { pigs.removeIf(p -> p.getId().equals(id)); } // 查看小猪情况 public void viewPigInfo(String id) { for (Pig p : pigs) { if (p.getId().equals(id)) { System.out.println("ID: " + p.getId() + ", 体重: " + p.getWeight()); break; } } } } // 主程序 public class Main { public static void main(String[] args) { PigManagementSystem system = new PigManagementSystem(); // 示例操作 system.addPig("001", 50); // 新增小猪 system.updatePigWeight("001", 70); // 修改小猪重量 system.viewPigInfo("001"); // 查看信息 system.pigLeaving("001"); // 小猪出栏 // 可以添加更多的用户交互,如循环处理菜单选择 } } ``` 这个例子提供了个基础框架,实际应用中可能需要更复杂的功能,比如数据库集成、错误处理等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值