洛谷UVA 12930 Bigger or Smaller
Description
给定若干对长度 \(\leqslant 100\) 的浮点数 \(a,b\) ,比较两者的大小。
Solution
经过读题可以发现,我们不能使用朴素方法(double)来存储数据。请注意,数字长度可能达到 \(100\) 位。于是,我们想到了一种很简单容易实现的方法:字符串模拟。
由于 C++ 的 string 头文件自带字典序比较,我们可以直接使用字典序模拟数字的比较。
但是,还有一个问题。浮点数可能拥有长度不一的后缀 \(0\) 。例如,\(1.00\) 和 \(1.000\) 和 \(1.0\) 等都是相等的。我们需要设法去除这个后缀。这也是这道题的难点。
首先,我们只需要关注小数部分,即小数点 . 后面的子串。我们遍历小数部分每个数,如果当前位是 \(0\) ,那么我们就进入内层循环。在内层循环里,我们逐个数位往后筛查,直到当前位不是 \(0\) 为止。如果当前内层循环已经到达字符串末尾,则代表后面都是后缀 \(0\) ,可以省略;否则这就是一个普通镶嵌在数字中的 \(0\) 。
Code
#include <iostream>
#include <string>
using namespace std;
string a, b;
int idx = 1;
string shorten_float_number(string n) { // 去除后缀0
int ans = n.size(); // 初始没有后缀
for (int i = n.find_first_of('.'); i < n.size(); i++) { // 从小数点一直循环到结束
if (n[i] == '0') { // 如果当前位是0,就需要进行判断是否为后缀
int j = i; // 从当前位开始循环
while (n[j++] == '0'); // 看最后哪里不是0
j--; // 多加了一个,减掉
if (j == n.size()) { // 如果到头了
ans = i + 1; // 那么就确定了答案
break;
}
}
}
return n.substr(0, ans); // 返回去除后缀的字符串
}
int main() {
while (cin >> a >> b) {
a = shorten_float_number(a), b = shorten_float_number(b);
string a_integer = a.substr(0, a.find_first_of('.')), b_integer = b.substr(0, b.find_first_of('.'));
string a_float = a.substr(a.find_first_of('.') + 1, a.size()), b_float = b.substr(b.find_first_of('.') + 1, b.size());
cout << "Case " << idx << ": ";
idx++;
if (a_integer != b_integer) { // 先判断整数部分
cout << (a_integer > b_integer ? "Bigger" : "Smaller") << endl;
continue;
}
if (a_float != b_float) { // 再判断小数部分
cout << (a_float > b_float ? "Bigger" : "Smaller") << endl;
continue;
}
cout << "Same" << endl; // 如果都不是,那就是相等
}
return 0;
}
蟹蟹阅读!

浙公网安备 33010602011771号