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
结尾无空行
正确代码:
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int main() {
int n, w1 = 0, w2 = 0;
string a, b, c1, c2;
cin >> n >> a >> b;
int i = 0, num = 0, mark1 = 0, mark2 = 0;
for (string::iterator it = a.begin(); it != a.end(); it++) {
if (it + 1 != a.end()) {
if (*it == '0')
num++;
else if (*it == '.') {
num--;
break;
}
else
break;
}
}
if (num != 0)
a.erase(a.begin(), a.begin() + num);
num = 0;
for (string::iterator it = b.begin(); it != b.end(); it++) {
if (it + 1 != b.end()) {
if (*it == '0')
num++;
else if (*it == '.') {
num--;
break;
}
else
break;
}
}
if (num != 0)
b.erase(b.begin(), b.begin() + num);
int w3 = 0, w4 = 0, w5 = 0, w6 = 0;
if (a[1] == '.' && a[0] == '0') {
for (string::iterator it = a.begin() + 2; it != a.end(); it++) {
w5++;
}
}
if (b[1] == '.' && b[0] == '0') {
for (string::iterator it = b.begin() + 2; it != b.end(); it++) {
w6++;
}
}
if (a[1] == '.' && a[0] == '0') {
for (string::iterator it = a.begin() + 2; it != a.end(); it++) {
if (*it != '0') {
break;
}
else
w3++;
mark1 = 1;
}
a.erase(a.begin(), a.begin() + 2 + w3);
}
if (b[1] == '.' && b[0] == '0') {
for (string::iterator it = b.begin() + 2; it != b.end(); it++) {
if (*it != '0') {
break;
}
else
w4++;
mark2 = 1;
}
b.erase(b.begin(), b.begin() + 2 + w4);
}
for (string::iterator it = a.begin(); it != a.end(); it++) {
if (*it == '.') {
break;
}
w1++;
}
for (string::iterator it = b.begin(); it != b.end(); it++) {
if (*it == '.') {
break;
}
w2++;
}
if (mark1 == 0 && a.find('.') != string::npos) {
a.erase(a.begin() + a.find('.'));
}
if (mark2 == 0 && b.find('.') != string::npos) {
b.erase(b.begin() + b.find('.'));
}
if (n > w1) {
for (int j = 0; j < n - w1; j++) {
a += '0';
}
}
if (n > w2) {
for (int j = 0; j < n - w2; j++)
b += '0';
}
int k = 0;
for (k = 0; k < n;k++) {
if (a[k] != '0' && b[k] != '0') {
break;
}
}
if (k == n) {
cout << "YES " << "0." << a << "*10^" << 0;
return 0;
}
for (i = 0; i < n; i++) {
if (a[i] != b[i]) {
break;
}
}
for (int j = 0; j < n; j++) {
c1 += a[j];
c2 += b[j];
}
if (i < n || (w1 - w5) != (w2 - w6)) {
cout << "NO " << "0." << c1 << "*10^" << w1 - w5 << " " << "0." << c2 << "*10^" << w2 - w6;
}
else {
cout << "YES " << "0." << c1 << "*10^" << w1 - w5;
}
return 0;
}
本题一开始测试点3,4,6都错误,我发现我忽略了小于0的情况(只考虑了大于0);忽略了最高位为0时,需要去除0;忽略了小数部分后面加0不影响结果。
以下是上述情况的例子:
3 12300 0012358.9
5 00.01 0.0001
1 00.01 0.010
修改上述bug后,我发现我只有一个测试点6过不了,最终发现以下特殊情况答案错误:
3 0 0.000
经过调试程序我发现语句如下:
b.erase(b.begin(), b.begin() + num);
num=0时,即b.erase(b.begin(), b.begin() );是会删除b.begin()。
最后其实应该写个函数来对a,b两字符串进行处理,上述代码高度重复。