【PAT_Python解】1123 舍入

原题链接:PTA | 程序设计类实验辅助教学平台

参考资料:

github_tiny656 / PAT

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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新时代先锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值