题目链接

特殊的科学计数法

题目描述

给定一个正整数 (位数可达 ),请将其转写为科学计数法形式,形如:a.b*10^e 具体而言,有如下要求:

  • 之间的整数;
  • 为对 的第二位数字进行四舍五入后的小数部分(保留一位小数);
  • 为整数指数;

输出格式严格为 a.b*10^e,无多余空格。

解题思路

本题要求我们将一个以字符串形式给出的大正整数转换为特定格式的科学计数法。我们来分析 a.b*10^e 的各个组成部分。经过对多个测试用例的分析,题目中 “对 的第二位数字进行四舍五入” 这一描述,实际上是指将数字 规范化为 的形式后,对其进行四舍五入保留一位小数

这意味着,决定的关键在于原始数字的第三位数字

  1. 指数 : 对于一个长度为 的正整数 ,其指数 始终等于 。这是固定的,除非后续的四舍五入导致最高位的进位(例如 9.95... 进位成 10.0)。

  2. 基数 的确定: 我们需要根据第三位数字 来决定第二位 是否进位,并处理可能产生的连锁反应。

    • 情况一: 的长度小于3位。

      • 如果 只有1位 (),则没有第二、三位。输出为 d1.0*10^0
      • 如果 只有2位 (),则没有第三位。无需四舍五入,输出为 d1.d2*10^1
    • 情况二: 的长度大于等于3位,且第三位数字 根据四舍五入规则,“舍去”。我们直接取前两位数字即可。输出为 d1.d2*10^e。 例如,输入 994...,舍去,结果为 9.9*10^...

    • 情况三: 的长度大于等于3位,且第三位数字 需要“进位”,这会影响到第二位数字

      • 我们将第二位数字 加1。
      • 如果加1后的 小于10,那么第一位 不变,输出即为 d1.(d2+1)*10^e。例如 285... -> 进位 -> 2.8 变为 2.9
      • 如果加1后的 等于10(即原 是'9'),则小数位变为0,并向第一位 进位。
        • 如果 不是'9',则 加1。例如 299... -> 2.9 变为 3.0
        • 如果 也是'9',则 进位后变为10,这意味着基数要变成 1.0,同时指数 需要加1。例如 995... -> 9.9 变为 10.0 -> 1.0*10^(e+1)

代码

#include <iostream>
#include <string>
#include <vector>

using namespace std;

void solve() {
    string n;
    cin >> n;
    int len = n.length();
    int e = len - 1;

    int a = n[0] - '0';
    int b = 0;

    if (len > 1) {
        b = n[1] - '0';
    }

    if (len > 2) {
        if (n[2] >= '5') {
            b++;
        }
    }

    if (b == 10) {
        b = 0;
        a++;
    }
    
    if (a == 10) {
        a = 1;
        e++;
    }

    cout << a << "." << b << "*10^" << e << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    solve();
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String n = sc.next();
        
        int len = n.length();
        int e = len - 1;

        int a = n.charAt(0) - '0';
        int b = 0;

        if (len > 1) {
            b = n.charAt(1) - '0';
        }

        if (len > 2) {
            if (n.charAt(2) >= '5') {
                b++;
            }
        }

        if (b == 10) {
            b = 0;
            a++;
        }
        
        if (a == 10) {
            a = 1;
            e++;
        }
        
        System.out.println(a + "." + b + "*10^" + e);
    }
}
def solve():
    n = input()
    le = len(n)
    e = le - 1
    
    a = int(n[0])
    b = 0

    if le > 1:
        b = int(n[1])

    if le > 2:
        if int(n[2]) >= 5:
            b += 1
            
    if b == 10:
        b = 0
        a += 1
        
    if a == 10:
        a = 1
        e += 1
        
    print(f"{a}.{b}*10^{e}")

solve()

算法及复杂度

  • 算法:字符串处理
  • 时间复杂度:。我们只关心输入字符串的长度和前三位字符,操作是常数时间。
  • 空间复杂度:,用于存储输入的数字字符串。