按字符串读取一位小数,分别实现普通四舍五入和向偶数舍入。
OJ: shumeng
题目 ID: CSP202605A
难度:未知
标签:字符串模拟浮点数
日期: 2026-07-31 16:22
形式化题目
给定 xxx.x 的非负实数,整数部分
- 四舍五入:
取 , 取 ; - 银行家舍入(向偶数舍入):
取 , 取 , 时若 为偶数取 、否则取 。
思路
避免浮点误差
读入一律按字符串处理,在小数点处切分得到整数部分和小数部分,避免 double 解析带来的精度问题。
两种规则只有半整数不同
两种规则在小数位为 integer_part & 1 即可。
代码
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-31 16:22
* update_at: 2026-08-17 22:40
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<long long> normal(n); // 普通四舍五入的结果
vector<long long> banker(n); // 银行家舍入的结果
for (int i = 0; i < n; i++) {
string value;
cin >> value;
// 按字符串切分,避免浮点解析误差
size_t dot = value.find('.');
long long integer_part = stoll(value.substr(0, dot));
int decimal_part = value[dot + 1] - '0';
// 普通四舍五入:小数位 >= 5 进位
normal[i] = integer_part + (decimal_part >= 5);
// 银行家舍入:小数位 > 5 进位;等于 5 时向偶数靠拢
banker[i] = integer_part;
if (decimal_part > 5 || (decimal_part == 5 && (integer_part & 1))) {
banker[i]++;
}
}
for (int i = 0; i < n; i++) {
if (i) cout << ' ';
cout << normal[i];
}
cout << '\n';
for (int i = 0; i < n; i++) {
if (i) cout << ' ';
cout << banker[i];
}
cout << '\n';
return 0;
}复杂度
- 时间:每个数只扫描一次字符串,设整数部分总长度为
,时间复杂度为 。 - 空间:需要保存两种结果各
个,空间复杂度 。
总结
半整数是两种舍入规则唯一不同的地方,直接按题面判断整数部分的奇偶性即可,不需要依赖语言内置的 round()(其策略可能不同)。