罗马货币最小硬币数转换问题求解(限制使用简单算术操作)
罗马货币最小硬币数转换问题求解(限制使用简单算术操作)
看起来你现在卡在这个罗马货币硬币转换的问题上了,而且还被限制不能用列表、复杂函数,只能靠基础算术来解决对吧?先别着急,我先帮你分析下现有代码的核心问题,再给你一个完全符合要求的解决方案。
你的现有代码的核心问题
1. 浮点数精度与单位定义错误
你用浮点数来定义货币单位(比如Semis = 0.5 * As),这会带来两个致命问题:
- 浮点数的精度误差:比如0.5*0.5在计算机中可能不是精确的0.25,会导致后续计算出现偏差
- 违背货币的整数特性:题目明确说明Quadrans是最小单位,所有其他货币的价值都是它的整数倍,完全不需要用浮点数
正确的做法是把所有货币价值都转换成以Quadrans为单位的整数,这样所有计算都用整数运算,彻底避免精度问题。
2. 硬币数量计算逻辑完全错误
你当前的计算逻辑(比如AureusP = (accountBalance * 0.25) // Aureus)完全不符合要求:
- 没有用剩余金额逐步扣除已分配的大面额总价值
- 公式本身逻辑混乱,只是简单用总金额减去上一个面额的数量,而非总价值
正确的逻辑应该是:
- 从最大面额开始,计算当前剩余金额能兑换多少个该面额的硬币
- 用剩余金额减去这些硬币的总价值(数量×面额的Quadrans值)
- 用更新后的剩余金额计算下一个更小的面额,以此类推
完全符合要求的解决方案(仅用基础算术)
步骤1:统一用Quadrans定义所有货币的整数价值
先把所有面额都转换成Quadrans的整数倍,彻底规避浮点数问题:
# 所有货币均以Quadrans为单位定义(整数,无浮点数) QUADRANS = 1 SEMIS = 2 * QUADRANS # 1 Semis = 2 Quadrans AS = 2 * SEMIS # 1 As = 4 Quadrans DUPONDIUS = 2 * AS # 1 Dupondius = 8 Quadrans SESTERTIUS = 2 * DUPONDIUS # 1 Sestertius = 16 Quadrans QUINARIUS = 2 * SESTERTIUS # 1 Quinarius = 32 Quadrans DENARIUS = 2 * QUINARIUS # 1 Denarius = 64 Quadrans ANTONINIANUS = 2 * DENARIUS # 1 Antoninianus = 128 Quadrans GOLD_QUINARIUS = 25 * QUINARIUS # 1 Gold Quinarius = 800 Quadrans AUREUS = 25 * DENARIUS # 1 Aureus = 1600 Quadrans
步骤2:用贪婪算法逐步计算硬币数量
严格从最大面额到最小面额计算,用临时变量保存剩余未转换的Quadrans数,所有操作都是基础整数算术:
# 获取用户输入 accountBalance = int(input("Enter Number of Quadrans: ")) remaining = accountBalance # 临时变量,保存剩余未转换的金额 # 从最大面额开始依次计算 aureus = remaining // AUREUS remaining -= aureus * AUREUS gold_quinarius = remaining // GOLD_QUINARIUS remaining -= gold_quinarius * GOLD_QUINARIUS antoninianus = remaining // ANTONINIANUS remaining -= antoninianus * ANTONINIANUS denarius = remaining // DENARIUS remaining -= denarius * DENARIUS quinarius = remaining // QUINARIUS remaining -= quinarius * QUINARIUS sestertius = remaining // SESTERTIUS remaining -= sestertius * SESTERTIUS dupondius = remaining // DUPONDIUS remaining -= dupondius * DUPONDIUS as_count = remaining // AS remaining -= as_count * AS semis = remaining // SEMIS remaining -= semis * SEMIS quadrans = remaining # 最后剩余的就是Quadrans数量(最小单位) # 按照示例格式输出 print(f"Aureus: {aureus}") print(f"Gold Quinarius: {gold_quinarius}") print(f"Antoninianus: {antoninianus}") print(f"Denarius: {denarius}") print(f"Quinarius: {quinarius}") print(f"Sestertius: {sestertius}") print(f"Dupondius: {dupondius}") print(f"As: {as_count}") print(f"Semis: {semis}") print(f"Quadrans: {quadrans}")
验证示例输入
当输入21432时,代码会输出和题目示例完全一致的结果:
Enter Number of Quadrans: 21432 Aureus: 13 Gold Quinarius: 0 Antoninianus: 4 Denarius: 1 Quinarius: 1 Sestertius: 1 Dupondius: 1 As: 0 Semis: 0 Quadrans: 0
符合你的限制条件
- 完全没有使用列表、字典或复杂函数,所有操作都是基础整数算术(取整、减法、乘法)
- 严格按照从最大到最小面额的顺序计算,保证硬币数量最少(该货币体系满足贪婪算法的最优性条件)
- 所有计算均为整数,彻底避免浮点数精度问题
备注:内容来源于stack exchange,提问作者theChosenOne
相关产品推荐
相关产品推荐

