熱門文章

2025年8月30日 星期六

ZeroJudge 解題筆記:d561. 被秒殺的四捨五入

作者:王一哲
日期:2025年8月30日


ZeroJudge 題目連結:d561. 被秒殺的四捨五入

解題想法


這題在 Python 可以用 decimal 函式庫作弊,將數值存成 Decimal 格式的浮點數再四捨五入即可。比較正常的作法,是用字串格式儲存數字,依序判斷數字的正負號、整數位、小數點後第一位、小數點後第二位,最後再依照小數點後第三位的值判斷是否要捨去或進位。

Python 程式碼


用 decimal 函式庫作弊,使用時間約為 24 ms,記憶體約為 3.9 MB,通過測試。
from decimal import Decimal, ROUND_HALF_UP
import sys

for line in sys.stdin:
    # 將 line 轉成 Decimal 格式的十進位數字,4捨5入到小數點後第2位
    n = Decimal(line.strip()).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    if str(n) == "-0.00":
        print("0.00")  # -0.00 要輸出為 0.00
    else:
        print(n)

使用時間約為 19 ms,記憶體約為 3.3 MB,通過測試。
import sys

for line in sys.stdin:
    s = line.strip()  # 字串格式的數字
    negative = False  # 是否為負值,預設為 False
    if s[0] == '-':  # 如果 s[0] 是負號
        negative = True  # negative 設定為 True
        s = s[1:]  # 刪除 s[0]
    num = int(s[0])  # 取整數位加到 num
    s = s[2:]  # 刪除整數位、小數點
    if s and s[0] != '0':  # 處理小數點後第 1 位
        num += int(s[0])*0.1
    s = s[1:]  # 刪除 s[0]
    if s and s[0] != '0':  # 處理小數點後第 2 位
        num += int(s[0])*0.01
    s = s[1:]  # 刪除 s[0]
    if negative: num = -num  # 如果是負值,乘以 -1
    if s and s[0] in '56789':  # 如果 s[0] 大於等於 5,要 4 捨 5 入
        if negative: num -= 0.01  # 如果是負值,減 0.01
        else: num += 0.01  # 如果是正值,加 0.01
    if str(num) == "-0.0": print("0.00")  # 如果轉成字串等於 -0.0,要印出 0.00
    else: print(f"{num:.2f}")


C++ 程式碼


使用時間約為 2 ms,記憶體約為 344 kB,通過測試。
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

int main() {
    string s;  // 字串格式的數字
    while(cin >> s) { 
        bool negative = false;  // 是否為負值,預設為 False
        if (s[0] == '-') {  // 如果 s[0] 是負號
            negative = true;  // negative 設定為 True
            s = s.substr(1);  // 刪除 s[0]
        }
        float num = (s[0]-'0')*1.0;  // 取整數位加到 num
        if (s.size() >= 2) s = s.substr(2);  // 刪除整數位、小數點
        if (!s.empty() && s[0] != '0') num += (s[0]-'0')*0.1;  // 處理小數點後第 1 位
        if (!s.empty()) s = s.substr(1);  // 刪除 s[0]
        if (!s.empty() && s[0] != '0') num += (s[0]-'0')*0.01;  // 處理小數點後第 2 位
        if (!s.empty()) s = s.substr(1);  // 刪除 s[0]
        if (negative) num = -1.0*num;  // 如果是負值,乘以 -1
        if (!s.empty() && s[0] >= '5') {  // 如果 s[0] 大於等於 5,要 4 捨 5 入
            if (negative) num -= 0.01;  // 如果是負值,減 0.01
            else num += 0.01;  // 如果是正值,加 0.01
        }
        if (to_string(num) == "-0.000000") cout << "0.00\n";  // 如果轉成字串等於 -0.000000,要印出 0.00
        else cout << fixed << setprecision(2) << num << "\n";
    }
    return 0;
}


沒有留言:

張貼留言