原题链接:PTA | 程序设计类实验辅助教学平台
参考资料:
Tips:以下Python代码仅个人理解,非最优算法,仅供参考!多学习其他大佬的AC代码!
测试点坑点:
测试点1:负整数的舍入
测试点5:第3种情况的四舍六入
测试点7:连续进位
测试点8:输入为负值,输出为零时,零的符号问题
AC代码
from decimal import * # 导入 decimal 模块以处理高精度浮点数
def round_number(method, number, precision):
"""
根据指定的舍入方法处理数字,并返回指定精度的结果。
:param method: 舍入方法(1: 四舍五入,2: 截断,3: 四舍六入五成双)
:param number: 待处理的数字字符串
:param precision: 要保留的小数位数
:return: 处理后的数字字符串
"""
context = getcontext() # 获取当前的上下文设置
context.prec = 300 # 设置精度位数,确保能处理足够大的数字
# 根据不同的舍入方法设置相应的舍入规则
if method == "1":
context.rounding = ROUND_HALF_UP # 四舍五入
elif method == "2":
context.rounding = ROUND_DOWN # 直接舍弃
elif method == "3":
context.rounding = ROUND_HALF_EVEN # 四舍六入五成双
# 将输入的数字转为 Decimal 类型,并量化到指定的小数位数
d = Decimal(number).quantize(Decimal("0." + "0" * precision))
# 将处理的结果转为字符串形式
ans = str(d)
# 如果结果为 0,确保其绝对值是 0
if d == 0:
d = abs(d) # 处理 0 的情况
# 输出结果字符串,去掉前面的正号
ans = str(d)
if ans[0] == "+":
ans = ans[1:]
return ans # 返回处理后的结果
# 主程序入口
n, d = map(int, input().split()) # 读取待处理数字的个数 n 和有效位数 d
for i in range(n):
op, num = input().split() # 读取每个操作指令和数字
print(round_number(op, num, d)) # 调用舍入函数并输出结果

尝试代码(测试点1和测试点7非零返回,暂时不继续想了,好多测试点,纯模拟题,不算法)
def cmd2(num, dot, bit):
# 操作 2,舍弃有效位后面位数的操作
return num[:dot + bit + 1]
def cmd1(num, dot, bit):
# 操作 1,四舍五入
ans = []
if num[dot + bit + 1] >= '5':
index = dot + bit
carry = 0
# 模拟进位操作
while index >= 0:
if num[index] == '.':
ans.append('.')
else:
carry += int(num[index]) + (1 if index == dot + bit else 0)
ans.append(str(carry % 10))
carry //= 10
index -= 1
if carry > 0:
ans.append('1')
if num[0] == '-':
ans.append('-')
return ''.join(reversed(ans))
else:
# 四舍
return cmd2(num, dot, bit)
def process(num, cmd, bit):
# 找到小数点的位置
dot = num.find('.')
length = len(num)
# 位数不够补 0,使得小数点后的位数至少为 bit + 1
if length - dot - 1 < bit + 1:
num += '0' * (bit + 1 - (length - dot - 1))
if cmd == 1:
return cmd1(num, dot, bit)
elif cmd == 2:
return cmd2(num, dot, bit)
else:
# 有效位的后一位进行四舍六入
if num[dot + bit + 1] < '5':
return cmd2(num, dot, bit)
elif num[dot + bit + 1] > '5':
return cmd1(num, dot, bit)
else:
# 有效位的后一位是 5 时
flag = any(c != '0' for c in num[dot + bit + 2:])
if flag:
return cmd1(num, dot, bit)
else:
# 有效位的最后一位是偶数时舍去后面的数,否则进位
if int(num[dot + bit]) % 2 == 0:
return cmd2(num, dot, bit)
else:
return cmd1(num, dot, bit)
def main():
n, bit = map(int, input().split())
for _ in range(n):
line = input().strip().split()
cmd = int(line[0])
num = line[1]
# 输入是整数时,补上小数点再处理
if '.' not in num:
num += '.'
result = process(num, cmd, bit)
# 处理 -0.0 的情况
if result.startswith('-0.'):
result = result[1:] # 去掉负号
print(result)
if __name__ == "__main__":
main()

652

被折叠的 条评论
为什么被折叠?



