Python函数实现:调整小计凑整为总价四舍五入值并最小化偏差
需求说明
编写一个Python函数,接收价格列表prices,为每个price[i]取floor(向下取整)或ceil(向上取整),需满足:
- 调整后的小计之和等于原总价的四舍五入值
- 最小化调整后小计与原小计的绝对差之和
最终返回调整后的小计列表。
示例
输入
prices: [5.40, 3.30, 5.00]
输出
[6, 3, 5]
解释
5.40 + 3.30 + 5.00 = 13.70
13.70 四舍五入为 14
最小调整方式为对5.40取ceil、3.30取floor。
用户现有代码
prices = [5.40,3.30, 5.00] total_price = 0 for price in prices: total_price+=price total_avg = round(total_price) print("total_avg:",total_avg) prices.sort() min_price = prices[0] max_price = prices[-1] print("min_price:",min_price) print("max_price:",max_price)
代码输出
>>>total_avg: 14 >>>min_price: 3.3 >>>max_price: 5.4
完整解决方案
核心思路
- 先计算所有价格的floor值总和,对比目标总和(原总价四舍五入后的值),得出需要将多少个floor值改为ceil值(每个ceil比floor大1,差值即为需要修改的数量)。
- 要最小化总绝对差,优先选择ceil操作后与原价格差值最小的价格进行修改(即原价格小数部分越大,ceil的成本越低)。
- 记录每个价格的原索引,避免排序后丢失原位置信息,最后还原顺序得到结果。
完整代码
import math def adjust_prices(prices): total = sum(prices) target = round(total) # 存储每个价格的ceil操作成本、原索引、floor值 price_details = [] for idx, p in enumerate(prices): floor_p = math.floor(p) # ceil操作的成本:ceil(p) - p = 1 - 小数部分 ceil_cost = 1 - (p - floor_p) price_details.append((ceil_cost, idx, floor_p)) # 计算初始floor总和与目标的差值 floor_sum = sum(detail[2] for detail in price_details) need_ceil_count = target - floor_sum # 按ceil成本升序排序,优先修改成本最低的 price_details.sort() # 生成结果列表 result = [0] * len(prices) for i in range(len(price_details)): cost, idx, floor_p = price_details[i] if i < need_ceil_count: result[idx] = floor_p + 1 else: result[idx] = floor_p return result # 测试示例 prices = [5.40, 3.30, 5.00] print(adjust_prices(prices)) # 输出: [6, 3, 5]
代码说明
- 遍历价格时记录ceil操作的成本,成本越小意味着修改后增加的绝对差越少。
- 通过排序筛选出最适合修改的价格,保证总绝对差最小。
- 保留原索引信息,确保最终结果的顺序与输入列表一致。
内容的提问来源于stack exchange,提问作者iambdot
相关产品推荐
相关产品推荐

