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.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.
Sample Input 1:3 12300 12358.9Sample Output 1:
YES 0.123*10^5Sample Input 2:
3 120 128Sample Output 2:
NO 0.120*10^3 0.128*10^3
I don't think my way is simple enough. However, this is all I've got now and can
not find a simpler way.
Can anyone do better?
#include<iostream> #include<string> #include<sstream> using namespace std; string format(string s, int n) { int i = 0, exp = 0, cnt = 0; stringstream ss; ss << "0."; bool dot = false, is_zero = true; while (i < s.size() && (s[i] == '0' || s[i] == '.')) { if (s[i] == '.') dot = true; else if (dot) --exp; ++i; } for (int j = i; j < s.size(); ++j) { if (s[j] == '.') dot = true; else if (cnt < n) { ++cnt; ss << s[j]; if (s[i] != '0') is_zero = false; } if (!dot) ++exp; } while (cnt < n) { ss << "0"; ++cnt; } ss << "*10^" << (is_zero ? 0 : exp); ss >> s; return s; } int main() { int n; string a, b; cin >> n >> a >> b; string sa = format(a, n); string sb = format(b, n); if (sa == sb) cout << "YES " << sa; else cout << "NO " << sa << " " << sb; return 0; }
It's funny that I looked into this problem again today and really got a little better. Which makes me feel great!
#include <string> #include <iostream> #include <vector> #include <algorithm> #include<sstream> #include<unordered_map> using namespace std; string getResult(string &str, int n) { stringstream ss; ss << "0."; int dot = -1, s = -1; for (int i = 0; i < str.size(); ++i) { if (str[i] == '.') dot = i; else if (str[i] == '0' && s == -1) continue; else if (ss.str().size() < n + 2) { if (s == -1) s = i; ss << str[i]; } } while (ss.str().size() < n + 2) { ss << '0'; } if (dot == -1) dot = str.size(); else if (dot < s) --s; if (s == -1) s = dot; ss << "*10^" << (dot - s); return ss.str(); } int main() { int n; string s1, s2; cin >> n >> s1 >> s2; s1 = getResult(s1, n); s2 = getResult(s2, n); if (s1 == s2) cout << "YES" << " " << s1; else cout << "NO" << " " << s1 << " " << s2; return 0; }