999瓶水一瓶毒药,10只小鼠,使用python暴力编程

1000瓶水中999是水,一瓶是毒,10只小白鼠,小鼠无论喝多少毒水都是在30分钟后死亡,有足够的吸管和空白瓶,50分钟内验证出毒瓶,给出有死亡小鼠序列号,输出有毒瓶号。这个题目应该有10多年了,但一直没找到解决的代码,本人写了一个,虽然解决了问题,但感觉很笨很暴力,贴出代码,请大家指正。

def test(n):
    list_death = []
    test = []
    mouse = []
    for i in range(10):     # 建立10个小鼠列表,每个列表其二进制某一位是1,数字放到哪一组,表示小鼠喝几号瓶
        mouse.append([])
    for i in range(1, 1001):        
        test.append(i)
    for i in test:
        if i & 0b1 ==1:
            mouse[0].append(i)
        if i & 2 == 2:
            mouse[1].append(i)
        if i & 4 == 4:
            mouse[2].append(i)
        if i & 8 == 8:
            mouse[3].append(i)
        if i & 16 == 16:
            mouse[4].append(i)
        if i & 32 == 32:
            mouse[5].append(i)
        if i & 64 == 64:
            mouse[6].append(i)
        if i & 128 == 128:
            mouse[7].append(i)
        if i & 256 == 256:
            mouse[8].append(i)
        if i & 512 == 512:
            mouse[9].append(i)
    print(f'第8号小鼠共喝{len(mouse[7])}瓶,没毒死也撑死了')
    list_death = []
    for i in n:
        list_death.append(mouse[i])     # 根据死亡小鼠序列号,将相应小鼠列表中序列号列表拿出
    for item in list_death:             # 建立未包含死亡小鼠序列号列表
        if item in mouse:
            mouse.remove(item)
    temp1 = []
    
    result = 0
    for list1 in list_death:        # 将列表转换成集合用于比较数据,建立死亡小鼠序号集合列表
        temp1.append(set(list1))
    comment_element = temp1[0]      # 找出死亡小鼠集合中都包含的瓶数字
    temp_comment_set = set()
    for i in range(len(temp1)):
        comment_element = comment_element.intersection(temp1[i])
    for number in comment_element:      # 找出死亡小鼠集合中都包含的数字是否包含在未死亡小鼠组中,如果包含则剔除
        for list2 in mouse:
            if number in list2:
                temp_comment_set.add(number)
    result = comment_element.difference(temp_comment_set)   # 最终保留的一个数字是毒瓶号
    
    print(f'死亡序号是{n}的小鼠,有毒瓶是第{result}瓶')

test([3, 5, 6, 7, 8, 9])8号小鼠共喝489瓶,没毒死也撑死了
死亡数是[3, 5, 6, 7, 8, 9]的小鼠,有毒瓶是第{1000}
要确定哪个子有毒酒,可以采用二进制分治法的思想,每次将子分为两组,每组50个。通过实验观察哪一组的鼠死掉,就可以排除掉剩下的一半子。这样,最多需要经过三次这样的过程,因为每次都可以排除一半的选项。 以下是这个过程的Java编程流程图示意图的大致思路: 1. 第一次测试 (n = 100): - 创建一个数组 `mice` 存储老鼠信息,初始值全为活鼠。 - 遍历子数组,对每个子标记为 "未检测" 或 "已检测且无死亡"。 2. 第二次测试 (n = 50): - 取 `mice[0..49]` 和 `mice[50..99]` 分别放入两个小组。 - 对第一个小组喂食,观察是否有死亡。如果所有都活着,则毒酒在第二个小组;如果有死亡,则在有死亡的那部分查找。 3. 第三次测试 (n = 25, 12.5, 或者更少): - 根据第二次的结果,继续上述步骤,直到找到唯一死亡的那部分。 4. 最终结果: - 当只剩下一个子,且在这个子里喂食的老鼠死亡时,我们就能确定这是毒酒。 ```java // 假设有一个列表 bottles[] 代表100个子,其中只有一个有毒 List<String> bottles = ...; int miceRequired = 0; while (bottles.size() > 1) { int half = bottles.size() / 2; // 模拟喂食老鼠 for (String bottle : bottles.subList(0, half)) { if (isMiceDead(bottle)) { // 假设isMiceDead()返回是否发现死亡老鼠 // 更新毒酒范围 bottles = bottles.subList(half, bottles.size()); miceRequired += 1; // 记录每一步需要的新老鼠数量 } } } System.out.println("至少需要" + miceRequired + "只老鼠才能确定毒药在哪"); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值