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元!。

    学习了!

  • 相关阅读:
    noi 2011 noi嘉年华 动态规划
    最小乘积生成树
    noi 2009 二叉查找树 动态规划
    noi 2010 超级钢琴 划分树
    noi 2011 阿狸的打字机 AC自动机
    noi 2009 变换序列 贪心
    poj 3659 Cell Phone Network 动态规划
    noi 2010 航空管制 贪心
    IDEA14下配置SVN
    在SpringMVC框架下建立Web项目时web.xml到底该写些什么呢?
  • 原文地址:https://www.cnblogs.com/BlueBlueSea/p/9524615.html
Copyright © 2011-2022 走看看