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;
}