点击查看代码
#include <bits/stdc++.h>
using namespace std;
// 【优化1】传引用 &,原地修改 A,避免 1000 次 vector 的深拷贝操作
void mul(vector<int>& A, int b) {
int t = 0;
for (int i = 0; i < A.size() || t; i++) {
if (i < A.size()) t += A[i] * b;
else A.push_back(0); // 位数增加了,直接扩容
A[i] = t % 10;
t /= 10;
}
// 去除可能产生的前导 0
while (A.size() > 1 && A.back() == 0) A.pop_back();
}
int main() {
// 竞赛必备:解除 cin/cout 与 stdio 的同步,加速读写
ios::sync_with_stdio(0); cin.tie(0);
int n;
string d;
if (!(cin >> n >> d)) return 0;
int k = 0; // 记录小数点后有多少位数字
vector<int> A;
// 逆序遍历,顺便过滤掉小数点,省去手写 reverse
for (int i = d.size() - 1; i >= 0; i--) {
if (d[i] == '.') {
k = d.size() - 1 - i;
} else {
A.push_back(d[i] - '0');
}
}
// 核心操作:将小数视作大整数,连乘 n 次 2
while (n--) mul(A, 2);
// 【防越界补丁】如果乘出来的结果非常小(比如 0.001 * 2^0),A 的长度可能小于 k
// 用 0 补齐高位,保证 A[k-1] 存在
while (A.size() <= k) A.push_back(0);
// 四舍五入逻辑:看小数点后第一位(即 A[k-1])是否大于等于 5
int carry = (k > 0 && A[k - 1] >= 5) ? 1 : 0;
vector<int> ans;
// 提取整数部分(从索引 k 开始一直到最高位),并处理进位
for (int i = k; i < A.size() || carry; i++) {
if (i < A.size()) carry += A[i];
ans.push_back(carry % 10);
carry /= 10;
}
// 清理最终整数部分的前导零(比如 0013 变成 13)
while (ans.size() > 1 && ans.back() == 0) ans.pop_back();
// 如果整数部分完全为空(比如原本就是 0),保证至少输出一个 0
if (ans.empty()) ans.push_back(0);
// 逆序输出最终答案
for (int i = ans.size() - 1; i >= 0; i--) cout << ans[i];
cout << '\n';
return 0;
}