更多PAT甲级题解--acking-you.github.io

题目

OJ平台

题目分析

这道题有有点坑坑的,最开始的前情提要过于的晦涩,开始无故就说一个机器只能保存三个有效数字,结果没给出丝毫有用的信息总结! 我后面翻了下别人的题解,发现原来是这个题意:

给出两个数,问将它们写成保留N位小数的科学计数法后是否相等。如果相等,输出YES,输出他们的科学记数法表示方法。如果不相等输出NO,分别输出他们的科学计数法

好了,题意弄懂了,准备开始敲代码吧!

代码详解

得到科学计数法的指数大小

直接利用 '.'第一个非0有效数 的位置关系可以得到转换为科学计数法时的指数大小!

int get_len(string& s) {                                                    //@用于处理指数的大小
    int pos = s.find('.');
    int start = 0;
    while (start < s.size() && (s[start] == '0' || s[start] == '.'))start++;
    if (pos == string::npos)pos = s.size();
    if (start == s.size())return 0;         //全是0的情况
    if (pos > start)return pos - start;     //小数点在第一位有效数字后面
    return pos - start + 1;                 //小数点在第一位有效数字前面
}

取出N位有效数字(不够用0填补)

string get_str(string& s) {                                                 //@返回答案字符串
    string t = "";
    int n = N;
    int cnt = 0;
    int start = 0;
    while (start < s.size() && (s[start] == '0' || s[start] == '.'))start++;//处理前导0
    for (int i = start; i < s.size(); i++) {
        if (s[i] == '.')
            continue;
        t.push_back(s[i]);
        cnt++;
        if(cnt==n)
            break;
    }
    if (cnt < n) {
        t += string(n - cnt, '0');          //如果数字不够,补'0'
    }
    return t;
}

输入和输出

void solve() {                                                              //@处理总输入输出的问题
    cin >> N >> s1 >> s2;
    int s1_n = get_len(s1);
    int s2_n = get_len(s2);
    string ss1 = move(get_str(s1));
    string ss2 = move(get_str(s2));
    if (ss1 == ss2) {
        printf("YES 0.%s*10^%d", ss1.c_str(), s1_n);
    } else {
        printf("NO 0.%s*10^%d 0.%s*10^%d", ss1.c_str(), s1_n, ss2.c_str(), s2_n);
    }
}

整合代码提交

效率勉强还行🐱‍🏍

#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int N;
int get_len(string& s) {                                                    //@用于处理指数的大小
    int pos = s.find('.');
    int start = 0;
    while (start < s.size() && (s[start] == '0' || s[start] == '.'))start++;
    if (pos == string::npos)pos = s.size();
    if (start == s.size())return 0;         //全是0的情况
    if (pos > start)return pos - start;     //小数点在第一位有效数字后面
    return pos - start + 1;                 //小数点在第一位有效数字前面
}
string get_str(string& s) {                                                 //@返回答案字符串
    string t = "";
    int n = N;
    int cnt = 0;
    int start = 0;
    while (start < s.size() && (s[start] == '0' || s[start] == '.'))start++;//处理前导0
    for (int i = start; i < s.size(); i++) {
        if (s[i] == '.')
            continue;
        t.push_back(s[i]);
        cnt++;
        if(cnt==n)
            break;
    }
    if (cnt < n) {
        t += string(n - cnt, '0');          //如果数字不够,补'0'
    }
    return t;
}
void solve() {                                                              //@处理总输入输出的问题
    cin >> N >> s1 >> s2;
    int s1_n = get_len(s1);
    int s2_n = get_len(s2);
    string ss1 = move(get_str(s1));
    string ss2 = move(get_str(s2));
    if (ss1 == ss2) {
        printf("YES 0.%s*10^%d", ss1.c_str(), s1_n);
    } else {
        printf("NO 0.%s*10^%d 0.%s*10^%d", ss1.c_str(), s1_n, ss2.c_str(), s2_n);
    }
}
int main() {
    solve();
    return 0;
}