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
一,注意点
1,本题对字符串的处理的写法分为两步是最好的,并且这两步是对小于1的数和大于1的数统一处理的,第一步是去除前导零并且定位10的幂次,第二步是确定精度。涉及到我的很多不完善的细节。
2,str.erase()删除某个值,不用str.earse(str.find('.')),应当用str.erase(str.begin()+str.find('.')),因为erase()后面跟的是指针。
3,str.length()的时间复杂度是O(1),可常使用。
4,本题的输入可以是00123.43,所以就算不是小数也得有去除前导0的过程。
二,我的WA代码
#include<iostream>
#include<string>
using namespace std;
int N = 0;
string store_judge_print(string str) {
string ans;
int len = str.length();
int pos = 0;
while (str[0] == '0'&&pos < len) {
str.erase(str.begin());
pos++;
}
if (pos < len&&str[0] == '.') {
int num_of_zero = 0;
ans = "0.";
str.erase(str.begin());
pos++;
while (str[0] == '0'&&pos < len) {
str.erase(str.begin());
num_of_zero++;
pos++;
}
if (pos == len) {
num_of_zero = 0;
}
int num_of_real_digit = 0;
int i = 0;
while (i < len - pos && num_of_real_digit < N) {
ans += str[i++];
num_of_real_digit++;
}
while (num_of_real_digit < N) {
ans += '0';
num_of_real_digit++;
}
if (num_of_zero > 0) {
ans += "*10^-";
ans += (num_of_zero + '0');
}
else {
ans += "*10^0";
}
}
else if(pos < len&&str[0] != '.'){
int num_of_mici = 0;
if (str.find('.') == string::npos) {
num_of_mici = str.length();
}
else {
num_of_mici = str.find('.');
str.erase(str.begin()+str.find('.'));
}
ans = "0.";
int len = str.length();
int num_of_digit = 0;
while (num_of_digit < N&&num_of_digit < len) {
ans += str[num_of_digit++];
}
while (num_of_digit < N) {
ans += '0';
num_of_digit++;
}
ans += "*10^";
ans += num_of_mici + '0';
}
return ans;
}
int main() {
string A, B;
string ans_1, ans_2;
scanf("%d", &N);
cin >> A >> B;
ans_1 = store_judge_print(A);
ans_2 = store_judge_print(B);
if (ans_1 == ans_2) {
printf("YES ");
cout << ans_1 << endl;
}
else {
printf("NO ");
cout << ans_1 << " " << ans_2 << endl;
}
// cout << ans_1 << endl;
return 0;
}
三,正确代码
#include<iostream>
#include<string>
using namespace std;
int n = 0;
string deal(string str, int &e) {
int k = 0;
//直接用str.length()>0表示字符串未结束,而不是pos<len
while (str.length() > 0 && str[0] == '0') {
str.erase(str.begin());
}
if (str[0] == '.') {
str.erase(str.begin());
//直接用e++和e--代表幂次,同时在寻找的过程中也进行了小数点的消除,完成字符串的处理,而不
//是我的小于1的数数num_of_zero,大于1的数find('.'),没有这种依次推进的感觉。
while (str.length() > 0 && str[0] == '0') {
str.erase(str.begin());
e--;
}
}
else {
while (k < str.length() && str[k] != '.') {
k++;
e++;
}
if (k < str.length()) {
str.erase(str.begin() + k);
}
}
if (str.length() == 0) {
e = 0;
}
int num = 0;
k = 0;
string res;
//精度处理,一个while可以解决,if用来判断精度和位数的关系,而不是我的两个while.
while (num < n) {
if (k < str.length())res += str[k++];
else res += '0';
num++;
}
return res;
}
int main() {
int e1 = 0, e2 = 0;
string str_1, str_2;
string ans_1, ans_2;
cin >> n >> str_1 >> str_2;
ans_1 = deal(str_1, e1);
ans_2 = deal(str_2, e2);
if (ans_1 == ans_2&&e1 == e2) {
cout << "YES" << " 0." << ans_1 << "*10^" << e1;
}
else {
cout << "NO" << " 0." << ans_1 << "*10^" << e1 << " 0." << ans_2 << "*10^" << e2;
}
return 0;
}