PAT甲级 1060 Are They Equal(25分)

1 篇文章 0 订阅

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

思路:模拟,我使用字符串表示标准化的浮点数,包括整数部分,小数部分和指数部分,最后对比字符串是否相同就可以了,本体判断条件较多,我主要从一下几个方面来判断:

1.是否有小数点,如果没有小数点则表示整数,去掉前导0后判断剩下的数字长度是否大于n,若大于则表示长度足够,直接截取前n为化为标准型;否则后面补0再化为标准型

2.若有小数点,从字符串开始找到第一个不为0的数字,记录该位置为head和小数点位置,去掉前导0;如果head于小数点之后,再分两种情况:①如果head在小数点后第一位,判断字符串从head开始到结束的长度是否大于等于n,。若大于大于n,长度足够,直接标准化;否则补0标准化。②如果head不在小数点后第一位,在上诉的基础上只要注意指数大小就可以了,这是指数为负。

如果head位于小数点前,去掉前导0的同时head和记录小数点位置的值也要做相应的改变,视去掉前导0和小数点之后的字符串的长度来判断是直接标准化还是补0再标准化

最后注意判断整数0和浮点数0

#include <bits/stdc++.h>
using namespace std;
string change(string s,int n)
{
    string str=""; //pos为小数点位置,head为第一个不为0的数字位置
    int pos=s.find(".");
    if(pos!=-1)
    {
        int head=-1;
        for(int i=0;i<s.size();i++)
        {
            if(isdigit(s[i])&&s[i]!='0')
            {
                head=i;
                break;
            }
        }
        //printf("head=%d pos=%d\n",head,pos);
        if(head==-1) //判断浮点数0
        {
            str="0.";
            for(int i=0;i<n;i++) str+='0';
            str+="*10^0";
            return str;
        }
        if(head>pos) //head在pos之后
        {
            if(pos>1) //去前导0
            {
                s=s.substr(pos-1);
                pos=1;
                head-=pos-1;
            }
            if(head==pos+1) //head于pos之后第一位
            {
                if(s.substr(head).size()>=n) str="0."+s.substr(head,n)+"*10^0"; //直接标准化
                else //补0标准化
                {
                    string temp=s.substr(head);
                    for(int i=0;i<n-temp.size();i++) temp+='0';
                    str="0."+temp+"*10^0";
                }
            }
            else //head不在pos之后第一位
            {
                if(s.substr(head).size()>=n) str="0."+s.substr(head,n)+"*10^"+to_string(-(head-pos-1));
                else
                {
                    string temp=s.substr(head);
                    for(int i=0;i<n-temp.size();i++) temp+='0';
                    str="0."+temp+"*10^"+to_string(-(head-pos-1));
                }
            }
        }
        else //head在pos之前
        {
            while(s[0]==0) //去前导0
            {
                s.erase(s.begin());
                pos--;
                head--;
            }
            s.erase(s.begin()+pos); //去小数点
            //标准化
            if(s.substr(head).size()>=n) str="0."+s.substr(head,n)+"*10^"+to_string(pos-head);
            else
            {
                string temp=s.substr(head);
                for(int i=0;i<n-temp.size();i++) temp+='0';
                str+="0."+temp+"*10^"+to_string(pos-head);
            }
        }
    }
    else //没有小数点,是整数
    {
        while(s[0]==0) s.erase(s.begin());
        if(s.size()==1&&s[0]=='0') //判断整数0
        {
            str="0.";
            for(int i=0;i<n;i++) str+='0';
            str+="*10^0";
            return str;
        }
        int len=s.size();
        if(s.size()>=n) str="0."+s.substr(0,n)+"*10^"+to_string(len);
        else
        {
            for(int i=0;i<n-len;i++) s+='0';
            str="0."+s+"*10^"+to_string(len);
        }
    }
    return str;
}
int main()
{
    int n;
    string a,b;
    cin>>n>>a>>b;
    string ca=change(a,n),cb=change(b,n);
    if(ca==cb) cout<<"YES "<<ca;
    else cout<<"NO "<<ca<<" "<<cb;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值