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

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

题目:

样例:

|--------|
| 2 3.14 |
[输入]

|----|
| 13 |
[输出]

思路:

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

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

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

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

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

cpp 复制代码
// 高精度乘以低精度 模板
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;
}

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

cpp 复制代码
// 高精度加法模板
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;
}

代码详解如下:

cpp 复制代码
#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;	
}

最后提交:

相关推荐
lixinnnn.2 分钟前
优先级队列:最小函数值
数据结构·算法
Xの哲學4 分钟前
Linux Worklet 深入剖析: 轻量级延迟执行机制
linux·服务器·网络·数据结构·算法
666HZ6666 分钟前
数据结构2.1 线性表习题
c语言·数据结构·算法
lihao lihao12 分钟前
C++ set和map
开发语言·c++·算法
学嵌入式的小杨同学18 分钟前
顺序表(SqList)完整解析与实现(数据结构专栏版)
c++·算法·unity·游戏引擎·代理模式
格林威19 分钟前
多光源条件下图像一致性校正:消除阴影与高光干扰的 6 个核心策略,附 OpenCV+Halcon 实战代码!
人工智能·数码相机·opencv·算法·计算机视觉·分类·视觉检测
iAkuya20 分钟前
(leetcode)力扣100 40二叉树的直径(迭代递归)
java·算法·leetcode
橘颂TA26 分钟前
【剑斩OFFER】算法的暴力美学——leetCode 103 题:二叉树的锯齿形层序遍历
算法·leetcode·结构与算法
2501_9011478326 分钟前
高性能计算笔记:灯泡开关问题的数学优化与常数级解法
笔记·算法·求职招聘
C_心欲无痕27 分钟前
JavaScript 常见算法与手写函数实现
开发语言·javascript·算法