蓝桥杯2024年第十五届省赛真题-R 格式(高精度乘法 + 加法)


蓝桥杯2024年第十五届省赛真题-R 格式(高精度乘法 + 加法)

原创 已于 2024-04-19 19:02:52 修改 · 粉丝可见 · 3k 阅读 · 16 · 18 · 本内容遵循CC 4.0 BY-SA版权协议 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 GEO检测 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/137791290

本题链接: 蓝桥杯2024年第十五届省赛真题-R 格式 - C语言网

题目:

样例:

cobol<br/>2 3.14<br/>
13

思路:

根据题意,结合数据范围,这是一道模板的高精度乘以低精度问题。

题意是double类型 d 与 2 的n 次幂相乘,最后四舍五入。

我们换一下视角,看作 对于double 类型 d ,与 n 个 2 相乘,最后四舍五入。

这样就很快解出答案了,就是对于double小数部分需要微调一下即可。

高精度乘法模板函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 高精度乘以低精度 模板
inline string mul(string A,int x)
{
vector<int>a; // 取出每一位
int len = A.size(); // 倒着取每一位,方便低位到高位的计算

for(int i = len - 1;~i;--i) a.emplace_back(A[i] - '0');

vector<int>tem; // 存储计算结果
int t = 0; // 存储临时进位数
for(int i = 0;i < len;++i)
{
int num = t + a[i] * x; // 开始每一位相乘
tem.emplace_back(num % 10); // 取计算结果个位
t = num / 10; // 计算进位
}

while(t > 0)
{
// 如果最后有高位的进位,我们进位
tem.emplace_back(t % 10);
t /= 10;
}

string ans = ""; // 存储最后计算结果
// 将结果转回为 string ,并返回结果
int temlen = tem.size();
for(int i = temlen - 1;~i;--i) ans += char(tem[i] + '0');
return ans;
}

高精度加法模板函数如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 高精度加法模板
inline string ADD(string A,string B)
{
vector<int>a,b;
int alen = A.size();
int blen = B.size();// 倒着取每一位,方便低位到高位的计算
for(int i = alen - 1;~i;--i) a.emplace_back(A[i] - '0');
for(int i = blen - 1;~i;--i) b.emplace_back(B[i] - '0');

vector<int>tem; // 存储计算结果
int t = 0; // 存储临时进位数
for(int i = 0;i < alen or i < blen;++i)
{
int num = t; // 开始每一位相加
if(i < alen) num += a[i];
if(i < blen) num += b[i];
tem.emplace_back(num % 10);// 取计算结果个位
t = num / 10;// 计算进位
}

while(t > 0)
{
// 如果最后有高位的进位,我们进位
tem.emplace_back(t % 10);
t /= 10;
}

string ans = ""; // 存储最后计算结果

// 将结果转回为 string ,并返回结果
int temlen = tem.size();
for(int i = temlen - 1;~i;--i) ans += char(tem[i] + '0');
return ans;
}

代码详解如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#define endl '\n'
#define int long long
#define YES puts("YES")
#define NO puts("NO")
#define umap unordered_map
#define All(x) x.begin(),x.end()
#pragma GCC optimize(3,"Ofast","inline")
#define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 2e6 + 10;
inline void solve();

signed main()
{
// freopen("a.txt", "r", stdin);
// IOS;
int _t = 1;
// cin >> _t;
while (_t--)
{
solve();
}
return 0;
}

// 高精度乘以低精度 模板
inline string mul(string A,int x)
{
vector<int>a; // 取出每一位
int len = A.size(); // 倒着取每一位,方便低位到高位的计算

for(int i = len - 1;~i;--i) a.emplace_back(A[i] - '0');

vector<int>tem; // 存储计算结果
int t = 0; // 存储临时进位数
for(int i = 0;i < len;++i)
{
int num = t + a[i] * x; // 开始每一位相乘
tem.emplace_back(num % 10); // 取计算结果个位
t = num / 10; // 计算进位
}

while(t > 0)
{
// 如果最后有高位的进位,我们进位
tem.emplace_back(t % 10);
t /= 10;
}

string ans = ""; // 存储最后计算结果
// 将结果转回为 string ,并返回结果
int temlen = tem.size();
for(int i = temlen - 1;~i;--i) ans += char(tem[i] + '0');
return ans;
}

// 高精度加法模板
inline string ADD(string A,string B)
{
vector<int>a,b;
int alen = A.size();
int blen = B.size();// 倒着取每一位,方便低位到高位的计算
for(int i = alen - 1;~i;--i) a.emplace_back(A[i] - '0');
for(int i = blen - 1;~i;--i) b.emplace_back(B[i] - '0');

vector<int>tem; // 存储计算结果
int t = 0; // 存储临时进位数
for(int i = 0;i < alen or i < blen;++i)
{
int num = t; // 开始每一位相加
if(i < alen) num += a[i];
if(i < blen) num += b[i];
tem.emplace_back(num % 10);// 取计算结果个位
t = num / 10;// 计算进位
}

while(t > 0)
{
// 如果最后有高位的进位,我们进位
tem.emplace_back(t % 10);
t /= 10;
}

string ans = ""; // 存储最后计算结果

// 将结果转回为 string ,并返回结果
int temlen = tem.size();
for(int i = temlen - 1;~i;--i) ans += char(tem[i] + '0');
return ans;
}

inline void solve()
{

int n;
string d;
bool vis = false; // 检查是否符合四舍五入
cin >> n >> d;

// 如果 d 是整数的情况
if((int)d.find(".") == -1)
{
while(n--)
{
d = mul(d,2);
}
}else
{
int pos = d.find("."); // 找到 小数点 . 的位置下标

int len = d.size() - pos - 1; // 计算小数部分长度
d.erase(d.begin() + pos); // 删掉 小数点 .

// 将 d 所有的数字当作整数相乘计算
while(n--)
{
d = mul(d,2);
}

pos = d.size() - len; // 更新小数点位置

// 查看小数点后一位是否符合四舍五入
if((d[pos] - '0') >= 5) vis = true;

// 删掉小数部分,保留整数
while(len--) d.erase(d.begin() + d.size() - 1);

if(vis) d = ADD(d,"1"); // 如果符合四舍五入,那么进一
}
cout << d << endl;
}

最后提交:


觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭

微信二维码

wechat pay

支付宝二维码

ali pay

蓝桥杯2024年第十五届省赛真题-R 格式(高精度乘法 + 加法)
http://blog.angindem.cn/2024/04/19/Angindem-CSDN博客/146_146/
作者
Angindem
发布于
2024年4月19日
许可协议