真假药丸称重问题

Posted 小小菜_v

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了真假药丸称重问题相关的知识,希望对你有一定的参考价值。

问题如下:

这里有十个外表一模一样的药瓶,每个瓶子里有许多一模一样的药丸,但其中有一瓶是假的。假药丸与真药丸唯一的差别是其重量。其中,真药丸每个1克重,而假药丸1.1克。现在给你一个电子称,但只给你一次称重的机会。能否找到一种方式,通过一次称重找出假药瓶?

解决思路如下:

问题升级1:

如果电子称不能超过50g (否则称重不准) 的称重怎么办?

问题解决思路:

对于第二个问题,可以不把第10瓶药纳入计算和称重范围
只称前9瓶,根据同样的逻辑推理,等于45g的话说明10号是假的,大于45g说明前面的9瓶有一瓶为假

问题升级2:

如果有两瓶假药,也只有一次称重的机会,你能否找出哪两瓶是假的?

问题升级3:

如何设计你的称重方式使得总重量尽可能小! 例如你的电子称无法容忍超过500 克的重量。

代码实现如下:

"""
这里有十个外表一模一样的药瓶,每个瓶子里有许多一模一样的药丸,但其中有2瓶是假的。
假药丸与真药丸唯一的差别是其重量。其中,真药丸每个1克重,而假药丸1.1克。
现在给你一个电子称,但只给你一次称重的机会。能否找到一种方式,通过一次称重找出假药瓶?
"""
from decimal import Decimal

class Pill(object):
    def __init__(self, final_weight, pill_num):
        self.pill_num = pill_num
        self.final_weight = final_weight
        self.pill_list = [1, 2]  # 设置第一,二瓶药取出的个数分别为1,2

    def get_pill_num_list(self):
        """取出1~10号药瓶的药丸数分别存在列表中"""
        for i in range(2, self.pill_num):
            self.pill_list.append(self.pill_list[i-1] + self.pill_list[i-2] + 1)
        print("每瓶药应取出的数存入列表中:%s" % self.pill_list)
        return self.pill_list

    def weighing(self):
        """获取多余的克数"""
        normal_weight = 0
        pill_list = self.get_pill_num_list()
        for i in pill_list:
            normal_weight += i
        print("正常药片的重量应为:%sg" % normal_weight)
        exceed_weight = self.final_weight - Decimal(normal_weight)
        print("药品重%s 克" % exceed_weight)
        return int(str(exceed_weight).replace(".", ""))

    def get_pill_index(self):
        """获取药瓶的下标"""
        exceed_num = self.weighing()
        num_list = self.pill_list
        for i in num_list:
            if exceed_num - i in num_list:
                return (num_list.index(i), num_list.index(exceed_num - i))


def main():
    final_weight = Decimal(input("请输入实际重量:"))
    pill_num = int(input("请输入需要称重药瓶数:"))
    if final_weight > 500:
        print("药品重量需小于500g")
        main()
    print("假药是%s号和%s号药瓶"% Pill(final_weight, pill_num).get_pill_index())


if __name__ == '__main__':
    main()

运行结果:

C:\\Users\\hhs\\AppData\\Local\\Programs\\Python\\Python36\\python.exe "F:/第3章 数据结构与算法/code/pill_demo.py"
请输入实际重量:364.9
请输入需要称重药瓶数:10
每瓶药应取出的数存入列表中:[1, 2, 4, 7, 12, 20, 33, 54, 88, 143]
正常药片的重量应为:364g
药品重0.9 克
假药是1号和3号药瓶

Process finished with exit code 0

综上可知:只要取出的药丸两两之和的这个数是唯一的,其他任意2瓶药丸相加都不等于这个数即可。
-----The END

以上是关于真假药丸称重问题的主要内容,如果未能解决你的问题,请参考以下文章

真假药丸称重问题

智力题(程序员面试6经典)

程序员面试智力题

12枚硬币,怎么3次称出假币

十二银元分三次找一假

让 Bootstrap 药丸在桌子内工作