zoukankan      html  css  js  c++  java
  • PAT 1060 Are They Equal[难][科学记数法]

    1060 Are They Equal(25 分)

    If a machine can save only 3 significant digits, the float numbers 12300 and 12358.9 are considered equal since they are both saved as 0.123×105​​ with simple chopping. Now given the number of significant digits on a machine and two float numbers, you are supposed to tell if they are treated equal in that machine.

    Input Specification:

    Each input file contains one test case which gives three numbers N, A and B, where N (<100) is the number of significant digits, and A and B are the two float numbers to be compared. Each float number is non-negative, no greater than 10100​​, and that its total digit number is less than 100.

    Output Specification:

    For each test case, print in a line YES if the two numbers are treated equal, and then the number in the standard form 0.d[1]...d[N]*10^k (d[1]>0 unless the number is 0); or NO if they are not treated equal, and then the two numbers in their standard form. All the terms must be separated by a space, with no extra space at the end of a line.

    Note: Simple chopping is assumed without rounding.

    Sample Input 1:

    3 12300 12358.9
    

    Sample Output 1:

    YES 0.123*10^5
    

    Sample Input 2:

    3 120 128
    

    Sample Output 2:

    NO 0.120*10^3 0.128*10^3

     题目大意:机器只能存储N位数,给出一个最多100位的浮点数,判断它们在机器中是否是相同的存储。

     //一开始想用字符数组,但是在字符数组中查找小数点的位置还要遍历,不如使用string直接find方便。

    #include <iostream>
    #include<stdio.h>
    #include<cmath>
    #include<vector>
    using namespace std;
    
    int main() {
        int n;
        string s1,s2;
        cin>>n;
        cin>>s1>>s2;
        int len1,len2;
        int pos=s1.find(".");
        pos==string::npos?len1=s1.size():len1=pos;
        pos=s2.find(".");
        pos==string::npos?len2=s2.size():len2=pos;
    
        string temp1=s1.substr(0,n);
        string temp2=s2.substr(0,n);
    
        if(len1!=len2){
            cout<<"NO ";
            cout<<"0."<<temp1<<"*10^"<<len1<<" ";
            cout<<"0."<<temp2<<"*10^"<<len2;
        }else{
            if(temp1==temp2){
                cout<<"YES ";
                cout<<"0."<<temp1<<"*10^"<<len1;
            }
            else{
            cout<<"NO ";
            cout<<"0."<<temp1<<"*10^"<<len1<<" ";
            cout<<"0."<<temp2<<"*10^"<<len2;
            }
        }
    
        return 0;
    }

    //提交一次之后,没有通过,牛客网上报错:

    测试用例:
    99 0 0.000

    对应输出应该为:

    YES 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000*10^0

    你的输出为:

    NO 0.0*10^1 0.0.000*10^1

     //但是我发现我不知道怎么处理,我写的这个bug存在问题,

    //看了大佬的代码之后发现,我对科学计数法并不太明白。

    代码来自:https://www.liuchuo.net/archives/2293

    #include <iostream>
    #include <cstring>
    #include<stdio.h>
    using namespace std;
    int main() {
        int n, p = 0, q = 0;
        char a[10000], b[10000], A[10000], B[10000];
        scanf("%d%s%s", &n, a, b);
        int cnta = strlen(a), cntb = strlen(b);
        for(int i = 0; i < strlen(a); i++) {//居然真的是遍历,我还以为需要字符串那样呢。
            if(a[i] == '.') {
                cnta = i;
                break;
            }
        }
        for(int i = 0; i < strlen(b); i++) {
            if(b[i] == '.') {
                cntb = i;
                break;
            }
        }
    
        while(a[p] == '0' || a[p] == '.') p++;//找到不为0的位置。
        while(b[q] == '0' || b[q] == '.') q++;
        if(cnta >= p)//这个小数点出现在非0位之后,如123.45,指数就为cnta-p=3
            cnta = cnta - p;
        else//小数点后仍有0位,如0.0002,那么指数就是负值,
            cnta = cnta - p + 1;
        if(cntb >= q)
            cntb = cntb - q;
        else
            cntb = cntb - q + 1;//
        if(p == strlen(a))//如果是0.000这样的形式,将其赋值为0.
            cnta = 0;//不置为0,有可能两个0判断不相等。
        if(q == strlen(b))
            cntb = 0;
        int indexa = 0, indexb = 0;
        while(indexa < n) {
            if(a[p] != '.' && p < strlen(a))//除了小数点以外都赋值,
                A[indexa++] = a[p];
            else if(p >= strlen(a))//当遍历完后,n较大时,仍然不够n位,那么后n位补0
                A[indexa++] = '0';
            p++;
        }
        while(indexb < n) {
            if(b[q] != '.' && q < strlen(b))
                B[indexb++] = b[q];
            else if(q >= strlen(b))
                B[indexb++] = '0';
            q++;
        }
        if(strcmp(A, B) == 0 && cnta == cntb)
            printf("YES 0.%s*10^%d", A, cnta);//读入和输出字符数组都可以用%s.
        else
            printf("NO 0.%s*10^%d 0.%s*10^%d" , A, cnta, B, cntb);
        return 0;
    }

    //深刻地学习了科学记数法

    1.科学记数法有两个重要的因素,就是小数点的位置,和首位非0位的位置,通过这两个可以确定指数,

    2.小数点的位置,怎么办呢?先初始化位字符串长度,对应整数,没有小数位。

    3.首位非0的元素也初始化为字符串的长度。

    4.需要注意的是如果首位非零元长度=字符串长度,那么这个字符串表示的数就是0.需要特殊处理,就是为0.0..0*10^0。否则计算指数。

    5.科学记数法如果不是0,那么处理后的结果,小数点后边一定要是非0元!。

    学习了!

  • 相关阅读:
    Https协议详解
    python3爬虫之入门和正则表达式
    浅谈httpsssl数字证书
    Linux常见配置文件
    标准C++中的string类的用法总结
    SourceInsight中 加namespace宏后,无法跳转问题解决
    ubuntu 12.04安装vmtools 问题解决
    Prolific PL2303 usb 转串口Win8 Win8.1驱动
    大津法阈值法代码
    opencv常用函数备忘
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/9524615.html
Copyright © 2011-2022 走看看