Problem: 这是一个经典的称重问题:有 12 个球,其中 11 个重量相同,1 个球重量不同(可能更重或更轻),要求设计一种策略,用尽可能少的天平称重次数找出这个不同的球,并判断它是更重还是更轻。
Solution Step: 可以通过分治法来解决这个问题。每次将球分成多个组,通过比较各个组的重量来确定异常小球所在位置,最终确定几号球是异常小球。
第一次比较:(1,2,3,4) vs (5,6,7,8);
第二次比较:(9,10,11,12) vs (5,6,7,8)
第三次比较:(1,2,9,10) vs (3,4,11,12)
这样的比较安排确保:所有12个球都至少参与了一次比较;即使组合之间有重叠,可以通过结果推断出异常球;每次比较都是4个球对4个球,保持平衡。
现在无论异常球是1-12中的哪一个,都能通过这三次比较的结果来验证。
Python代码实现:
import numpy as np
import random
def get_weight(balls, different_ball, is_heavier):
"""模拟称重过程
Args:
balls: 待称重的球序号列表
different_ball: 不同重量的球的序号(1-12)
is_heavier: True表示更重,False表示更轻
"""
left_total = sum(1 for b in balls[0] if b == different_ball)
right_total = sum(1 for b in balls[1] if b == different_ball)
if left_total > right_total:
return 1 if is_heavier else -1
elif left_total < right_total:
return -1 if is_heavier else 1
else:
return 0
def compare_weights(left, right, different_ball, is_heavier):
"""比较两组球的重量"""
balls = [left, right]
result = get_weight(balls, different_ball, is_heavier)
return result # 1表示左边重, -1表示右边重, 0表示相等
def verify_ball(different_ball: int, is_heavier: bool):
"""验证给定的不同球是否正确
Args:
different_ball: 用户声称的不同重量球的序号(1-12)
is_heavier: 用户声称球是更重(True)还是更轻(False)
"""
# 修改比较方案,确保12个球都参与比较
comparison_1 = compare_weights([1, 2, 3, 4], [5, 6, 7, 8], different_ball, is_heavier)
comparison_2 = compare_weights([9, 10, 11, 12], [5, 6, 7, 8], different_ball, is_heavier)
comparison_3 = compare_weights([1, 2, 9, 10], [3, 4, 11, 12], different_ball, is_heavier)
print(f"比较结果:")
print(f"1,2,3,4 vs 5,6,7,8: {'左重' if comparison_1 > 0 else '右重' if comparison_1 < 0 else '相等'}")
print(f"9,10,11,12 vs 5,6,7,8: {'左重' if comparison_2 > 0 else '右重' if comparison_2 < 0 else '相等'}")
print(f"1,2,9,10 vs 3,4,11,12: {'左重' if comparison_3 > 0 else '右重' if comparison_3 < 0 else '相等'}")
return True
def validate_input():
while True:
try:
ball_num = int(input("请输入不同重量的球的序号(1-12): "))
if 1 <= ball_num <= 12:
break
else:
print("请输入1-12之间的数字")
except ValueError:
print("请输入有效的数字")
while True:
weight = input("这个球是重了还是轻了?(heavy/light): ").lower()
if weight in ['heavy', 'light']:
return ball_num, weight == 'heavy'
print("请输入 heavy 或 light")
def main():
ball_num, is_heavier = validate_input()
result = verify_ball(ball_num, is_heavier)
if result:
print("你的答案与称重结果一致!")
else:
print("你的答案与称重结果不一致!")
if __name__ == "__main__":
main()
代码功能介绍:
通过对12个小球进行多次称重,来找出与其他11个球重量不同的小球。
首先定义get_weight函数:
- 接收两组球的序号和不同球的信息
- 计算不同重量的球在左右两边的数量
- 根据不同球是重还是轻返回称重结果
其次定义compare_weights函数:
- 对两组球进行重量比较
- 把两组球组装成天平左右两边的形式
- 调用
get_weight
得到称重结果
然后是定义verify_ball
函数:
- 进行三次不同组合的称重比较:
- 第一次:前8个球分成两组比较
- 第二次:后4个球和中间4个球比较
- 第三次:交叉组合比较 这三次比较可以确定任意一个异常球的位置和重量状态
测试验证代码称重结果如下:
在代码中防止系统盲目进行计算输出不正确的小球,在这里增加了用户的交互,通过在开始指定重量异常小球,来进行称重验证。最终确定异常小球是我们输入的目标球序号。
标签:different,12,python,小球,ball,个球,heavier,称重 From: https://blog.csdn.net/weixin_44979308/article/details/144561462