题目描述
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.
输入描述
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.
输出描述
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.d1…dN*10^k” (d1>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.
输入样例
3 12300 12358.9
输出样例
YES 0.123 * 10 ^ 5
题目大意
给定两个数,或为小数,或为整数,将它们统一表示成小数的科学计数法,即0.xxx……乘10的幂的形式,小数点后第一位不为0。保留N位,判断其是否相等,并输出对应结果。
分析
由于给定的A和B,长度可能很大,故将其以字符串的形式读入。先统计小数点前的有效位数count,即从第一个非零的数算起。如果count==0,则该数为纯小数。然后再从头开始遍历,找第一个不为零的字符的位置,然后从该位置开始,截取字符串长度为N的子串,注意去掉小数点。则该字串即为最终的有效位(小数位)。如果有效位位数不足N,则后面用0填充。
对于指数的确定:1、如果是纯小数,则从小数点后第一位开始,直到遇到某一位非零的数,然后用该数下标减去2,再取反得到。如:对于0.00251,如果要求保留三位,则第一位有效数字位2,按科学计数法,要将其左移两位,指数部分应为-2,得到0.251 * 10^(-2)。3、其他情况指数即为上面count的值。
#include <iostream>
using namespace std;
int count(string str) { //统计小数点前的有效位
int count=0;//保存位数
for (int i = 0; i < str.length() && str[i] != '.'; ++i) {
if (str[i] != '0') count++;//若非零,加一
else if (str[i] == '0' && count > 0) count++;//若为零,只要count此时>0,则可加一。即此步是为了在统计的同时不包含无效的前导0,形如0000123.258
}
return count;
}
string solution(string S, int &count, int N) {//count为引用类型,因为可能会对其进行修改
string str;//保存最终的小数位
int noZero = 0;//记录第一个有效位下标
int index;//S的下标索引
for (index = 0; index < S.length(); ++index) {
if (S[index] != '0' && S[index] != '.') break;//只要遇到某位为有效数字,结束循环
else noZero++;
}
if (count == 0 && index != S.length())//如果为纯小数且不恒为0
count -= noZero - 2;//对指数count进行处理
for (int j = noZero; str.length() < N && j < S.length(); ++j) {//从第一个 有效位算起,截取长度为N的子串
if (S[j] != '.') {//不包括小数点
str += S[j];//当前字符加入到str后
}
}
if (str.length() < N) {//最终有效位不足N位,后面用0补齐
for (int i = str.length(); i < N; ++i) {
str += '0';
}
}
return str;
}
int main() {
int N;
string A, B, strA, strB;
cin >> N >> A >> B;
int countA = count(A);//得到指数
int countB = count(B);//得到指数
strA = solution(A, countA, N);//得到小数位
strB = solution(B, countB, N);//得到小数位
if (countA == countB && strA == strB) {//比较,按要求输出
cout << "YES" << " ";
cout << "0." << strA << "*" << "10" << "^" << countA;
} else {
cout << "NO" << " ";
cout << "0." << strA << "*" << "10" << "^" << countA << " ";
cout << "0." << strB << "*" << "10" << "^" << countB;
}
}