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 × 1 0 5 0.123×10^5 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 N N, A A A and B B B, where N ( < 100 ) N (<100) N(<100) is the number of significant digits, and A A A and B B B are the two float numbers to be compared. Each float number is non-negative, no greater than 1 0 100 10^{100} 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
N
N,实数
A
,
B
A, B
A,B,让我们判断在精度范围内
A
B
A B
AB是否相等,用0.d[1]...d[N]*10^k
的科学计数法形式表示结果。
判断两个数是否相等,可以通过判断主体部分d[1]...d[N]
和指数部分k
是否分别相等来判断。
基于这个思路,我们可以分别提取输入实数的主体部分和指数部分,最后判断它们是否分别相等来解决这个问题。
-
对主体部分的提取:
- 如果输入数据中没有
.
,数据的有效部分就为主体部分 - 如果输入数据中出现了
.
,需要判断整数部分是否为0:如果为0,去除前面的0.00..
部分剩下的部分为主体部分,如果不为0,去除.
的部分为主体部分
- 如果输入数据中没有
-
对指数的提取:
与主体部分相同,同样要分为有无.
两种情况:- 如果输入数据中没有
.
,数据的有效位数即为指数 - 如果输入数据中出现了
.
,需要判断整数部分是否为0:如果不为0,.
之前的整数部分有效位数即为指数,如果为0,.
之后的小数部分前导0的位数取相反数即为指数
- 如果输入数据中没有
注:
- 本题的测试数据中会出现前导0和后导0,在进行提取之前需要先进行去除
测试样例
下面为一些测试样例:
3 0000.0 0
// YES 0.000*10^0
3 0.0521 0.0520
// NO 0.0521*10^-1 0.0520^10^-1
// NO 0.0521*10^-1 0.052^10-1 输出这种数据的程序也可以通过测试点,可能PTA测试点中没有这么严格的数据
3 00001.23000 1.23456
// YES 0.123*10^1
源码
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
struct Data
{
string digit;
int eff;
int preci;
Data() : digit(), eff(0), preci(0) {}
~Data() {}
void initialStatus(int N)
{
preci = N;
// 去除前导0
for (auto s = digit.begin(); *s == '0' && s+1 != digit.end(); s++)
{
if (*(s + 1) == '.')
break;
else if (*(s + 1) != '0')
{
digit.erase(s);
break;
}
else
{
digit.erase(s);
s--;
}
}
// 去除后导0
if(digit.find(".") != string::npos)
{
for (auto s = digit.rbegin(); *s == '0' && s+1 != digit.rend(); s++)
{
if (*(s + 1) == '.')
break;
else if (*(s + 1) != '0')
{
digit.erase(s.base()-1);
break;
}
else
{
digit.erase(s.base()-1);
}
}
}
// 处理0和0.0
if (digit == "0" || digit == "0.0")
{
digit = string(preci, '0');
eff = 0;
return;
}
// 计算指数和主体数据
eff = digit.find(".");
if (eff == string::npos)
eff = digit.size();
else if (eff == 1 && digit[eff - 1] == '0')
{
int cnt = 0;
for (auto i = eff + 1; digit[i] == '0' && i < digit.size(); i++)
{
cnt++;
}
digit.erase(0, cnt + 2);
eff = -cnt;
}
else
{
digit.erase(eff, 1);
}
}
};
ostream &operator<<(ostream &o, Data d)
{
o << "0." << d.digit.substr(0, d.preci) << "*10^" << d.eff;
return o;
}
int main()
{
int N;
Data d1, d2;
cin >> N >> d1.digit >> d2.digit;
d1.initialStatus(N);
d2.initialStatus(N);
if (d1.digit.substr(0, N) == d2.digit.substr(0, N) && d1.eff == d2.eff)
cout << "YES " << d1 << endl;
else
cout << "NO " << d1 << " " << d2 << endl;
return 0;
}