1 条题解

  • 0
    @ 2026-6-19 10:30:56

    📝 题目大意

    给定一个精确到小数点后三位的实数 XX0X<1000 \leq X < 100),输出时不保留小数部分末尾多余的 0,若小数部分全为 0 则连小数点一同去掉。

    💡 解题思路

    1. 题目分析:输入保证恰好有三位小数,因此字符串格式固定为 整数部分.三位小数。核心任务是删去末尾的 0,并在小数部分全为 0 时顺带删去小数点。数据范围极小(X<100X < 100),直接字符串处理即可。

    2. 算法推导

      • 将输入作为字符串读入,定位小数点 . 的位置 id
      • 从字符串末尾(即 id + 3 处)开始,向前扫描,跳过所有 '0' 字符,找到第一个非 '0' 的位置 r
      • r == id,说明小数部分三位全是 0(如 0.000),此时需要再向前退一位(r--),将该小数点也一并舍弃。
      • 最后输出字符串从第 1 位到第 r 位即可。
    3. 边界与细节

      • 输入如 0.000 时,r 最终会退到整数部分末尾,输出 0 而非 0.,这是 WA 的关键坑点。
      • 输入如 1.012 时,末尾非 '0'r 保持不变,原样输出。
      • 输入如 12.340 时,末尾一个 '0' 被跳过,输出 12.34
      • 注意 C++ 中 scanf("%s", s+1) 从下标 1 开始存储,方便后续下标与直观位置对应。

    ⏱️ 复杂度分析

    • 时间复杂度:扫描字符串定位小数点并删除末尾零,整体只需一次线性遍历,字符串长度固定为 6\sim 6,因此为 O(1)O(1)
    • 空间复杂度:仅使用一个字符数组存储输入字符串,长度为常数级别,O(1)O(1)

    💻 标准代码 (C++)

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
        char s[110]; scanf("%s", s + 1); // 从下标 1 开始读入字符串
        int l = strlen(s + 1), id = 0;
        for(int i = 1; i <= l; i++)      // 找到小数点的位置
            if(s[i] == '.'){
                id = i;
                break;
            }
        int r = id + 3;                  // 小数点后第三位(最后一位小数)
        while(s[r] == '0') r--;          // 去掉末尾的 0
        if(r == id) r--;                 // 若小数部分全为 0,去掉小数点
        for(int i = 1; i <= r; i++) printf("%c", s[i]); // 输出有效部分
        return 0;
    }
    
    • 1

    信息

    ID
    823
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者