![]() ![]() |
题目大意
给出两个超大的数,让你保存对应的有效数字,然后判断是否相等。思路解析
其中有两个坑:1. 不能四舍五入,直接暴力舍掉;
2. 最扯淡的一条:保存有效数字,不是让你用科学计数法保存,在科学计数法里,对有效数字的定义是
本题是把0也当做有效数字的,真是活久见,这个“BUG”找了一下午,或许是我见识太短浅了…… 做这种麻烦的题真是心累……从左边第一个不是0的数字起,到精确到的位数止,所有的数字都叫做这个数的有效数字(significant figure)。
示例代码
#include<iostream>
#include<string>
using namespace std;
string func(string str,int n) {
int index = -1,count = 0,point = -1;//index指向第一位有效数字的角标,count记录原式有效数字个数,point记录小数点位置
bool flag = true,flag2 = true;
for (int i = 0; i < str.length(); i++) {//先检查原式有效位数
if ((flag2 && str[i] == '0') || (flag2 && str[i] =='.')) continue;
flag2 = false;
if (str[i] != '.') {
count++;
}
}
for (int i = 0; i < str.length(); i++) {//找小数点和有效数字的起始位置
if (str[i] == '.') point = i;//找小数点
if (flag && str[i] == '0') continue;
if (index == -1 && str[i] != '.') {
index = i;
flag = false;
}
if (index != -1 && point != -1) break;
}
string res = "0.";
if (index == -1) {
string app(n, '0');
res = res + app + "*10^0";
return res;
}
point = point == -1 ? str.length() : point;
int k;
if (point < index)//小数点在后面
k = point - index + 1;//阶数
else
k = point - index;
if (count >= n) {//原式有效位数足够
int c = 0;
for (int j = index; j < str.length() && c < n; j++) {
if (str[j] != '.') {
res += str[j];
c++;
}
}
res = res + "*10^" + to_string(k);
}
else {//原式有效位数不够,需要补零
string app(n - count, '0');
int c = 0;
for (int j = index; j < str.length() && c < n; j++) {
if (str[j] != '.') {
res += str[j];
c++;
}
}
res = res +app + "*10^" + to_string(k);
}
return res;
}
int main() {
int n;
string a, b;
cin >> n >> a >> b;
int len = a.length() - b.length();
string s1 = func(a, n);
string s2 = func(b, n);
if (s1 == s2) {
printf("YES %s", s1.c_str());
}
else {
printf("NO %s %s", s1.c_str(), s2.c_str());
}
return 0;
}