天平称重的另类解法

问题描述:

用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量。如果有无限个砝码,但它们的重量分别是1,3,9,27,81,……等3的指数幂。神奇之处在于用它们的组合可以称出任意整数重量(砝码允许放在左右两个盘中)。本题目要求编程实现:对用户给定的重量,给出砝码组合方案,重量<1000000。要求程序输出的组合总是大数在前小数在后。可以假设用户的输入一定是一个大于0的整数。

例如:

用户输入:5,程序输出:9-3-1

用户输入:19,程序输出:27-9+1

思路分析:

1.将正整数转换为三进制数字,从低位到高位定位首次出现2的位置(如有),对应位加1转换为0(十进制加3的指数幂)。指数幂取负后相当于左托盘的砝码

2.得到的新整数重复上述操作。如此反复,直到三进制数字中不再含2。最终数字列表转换为3的指数幂,相当于右托盘的砝码

3.左右托盘砝码合并,按绝对值从大到小排序,带正负符号输出

例如:62转换为三进制2022,第一位加1(十进制加3的0次方,左托盘砝码:-1)得到63,转换为三进制2100,第四位加1(十进制加3的3次方,左托盘砝码:-27)得到90,转换为三进制10100(右托盘砝码:9、81),砝码组合:81-27+9-1

参考代码:

def ternary(num):
    """将十进制数字转换为从低位到高位排列的三进制数字列表"""
    num_list = []
    while num > 0:
        num_list.append(num % 3)
        num //= 3
    return num_list

num = int(input("请输入物品重量:"))
group = []  #定义存储砝码组合的列表
num_list = ternary(num)

while 2 in num_list:  #循环检查三进制数字列表中是否含2
    num += pow(3, num_list.index(2))  #定位首次出现2的位置,对应位加1转换为0(十进制加3的指数幂)
    group.append(-pow(3, num_list.index(2)))  #将指数幂取负加入砝码组合(左托盘)
    num_list = ternary(num)
    
#将最终不含2的数字列表转换为3的指数幂加入砝码组合(右托盘)
group.extend(pow(3, i) for i, v in enumerate(num_list) if v == 1)  
group.sort(key = lambda x: abs(x), reverse = True)  #按绝对值从大到小排序

print('砝码组合:', ''.join('%+d' %_ for _ in group).lstrip('+'))  #带正负符号输出

运行结果:

请输入物品重量:2023
砝码组合: 2187-243+81-3+1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值