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与浮点数a、b。请问两浮点数是否相等,如果是则输出YES,并输出有效形式。
思路:
其实问题就是在问科学计数法 + 排除掉有效数位外的数。
算法包括了两部分,一部分是“如何获得阶数”、第二部分是“如果获得尾数”,即有效数位问题。
先解决阶数问题:
假设有123.4444,小数点前的数是正阶数,即此时阶数ans = 3。 写成科学计数法0.1234444*10^4。
假设有 0000.1234,小数点前虽然有数,但要排除先导0,即应当为0.1234,
假设有0.001234,小数点后有0,则此时阶数应当为 ans = -2, 写成科学计数法为0.1234 * 10 ^-2。
可以知道阶数获得方法:如果有先导0,则排除掉先导0,如果此时是小数点,则删除掉小数点,然后再排除掉小数点后的0,并且每次都让阶数减一。
如果排除掉先导0后不是小数点,那么就去找小数点,小数点前每位数都让阶数加一。
遇到小数点后记得删除小数点。
再解决有效数位的问题:
假设现在是有效数位为3,123.4444在第一步处理后0.1234444*10^4。实际上是(s = 1234444, 阶数ans = 4), 超过有效数位的部分直接删除掉。
0.001234,写成科学计数法为0.1234 * 10 ^-2, 有效数位为5, s = 1234 , s.size() < 5,在s 后面补0就可以了。
参考代码:
#include<iostream>
#include<string>
using namespace std;
int n;
string a, b;
int change(string &s){
int ans = 0, idx = 0;
while(s.front() == '0') s.erase(s.begin());
if(s.front() == '.'){
s.erase(s.begin());
while(s.front() == '0') s.erase(s.begin()), ans--;
}else{
while(s[idx] != '.' && idx < s.size()) idx++, ans++;
if(idx < s.size()) s.erase(idx, 1);
}
if(s.size() == 0){
while(s.size() < n) s += '0';
return 0;
}
if(s.size() > n) s.erase(s.begin() + n, s.end());
while(s.size() < n) s += '0';
return ans;
}
int main(){
cin >> n >> a >> b;
int num1 = change(a), num2 = change(b);
if(a == b && num1 == num2){
printf("YES 0.%s*10^%d", a.c_str(), num1);
}else{
printf("NO 0.%s*10^%d", a.c_str(), num1);
printf(" 0.%s*10^%d", b.c_str(), num2);
}
return 0;
}