蓝桥杯2024年第十五届省赛真题-R 格式 题型:大数相乘

201 阅读1分钟

www.dotcpp.com/oj/problem3…

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;double d; cin >> n >> d;
	
	double t = d * pow(2, n);

	cout << (int)(t*10+5)/10 << endl;
	return 0;
}

image.png

看了一下n最大1000,2n2^n比较大,用快速幂:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL qmi(int a, int b)
{
	LL res = 1;

	while (b)
	{
		if (b & 1)res = res * a;

		b >>= 1;
		a = a * a;
	}
	return res;
}
int main()
{
	int n; double d; cin >> n >> d;

	double t = d * qmi(2, n);

	cout << (int)(t * 10 + 5) / 10 << endl;
	return 0;
}

image.png

2322^{32}都4e9了,这里210002^{1000},开long long都不好使,所以这道题就是让用字符串来模拟高精度大数乘法的。

#include<bits/stdc++.h>
#define  endl '\n'
using namespace std;

//模拟大数相乘
void mul(vector<int>& ver)
{
	int flag = 0;  //存储进位
    
	for (auto& x : ver)
	{
		x = x * 2 + flag; //每一位*2
		flag = x / 10;    //看是否有进位
		x = x % 10;       //取下一位
	}
	if (flag)ver.push_back(flag);  //进位加到末尾
}



int main()
{
	cin.tie(nullptr)->sync_with_stdio(false);
	int n; cin >> n;
	string s; cin >> s;

	reverse(s.begin(),s.end());  //从尾部开始相加

	//存储一下小数点位置,然后把小数点剔除后所有字符添加到ver里
	vector<int> ver;
	int flag = 0;
	for (int i = 0; i < s.size(); i++)
	{
		if (s[i] == '.')
		{
			flag = i;  //保存一下小数点位置
			continue;
		}
		else
		{
			ver.push_back(s[i]-'0');
		}
	}


	//相乘
	while (n--)
	{
		mul(ver);
	}

	reverse(ver.begin(),ver.end());  //相乘模拟完,恢复

    //从小数点开始,全部移除
	int bak = -1;
	while (flag--)  
	{
		bak = ver.back();  
		ver.pop_back();
	}

	//如果被移除的小数的最后一位大于等于5,就向前进1
	if (bak >= 5)
	{

		//首先翻转一下从尾巴开始往前进1,进完之后判断是否还要继续向前进1
		reverse(ver.begin(),ver.end());
		int flag = 1;
		for (int i = 0; i < ver.size(); i++)
		{
			ver[i] += flag;
			flag = ver[i] / 10;
			ver[i] = ver[i] % 10;
		}
		if (flag)  //最后还有进位就加在末尾
		{
			ver.push_back(flag); 
		}
		reverse(ver.begin(),ver.end());  //进位模拟完毕,翻转回来
	

	}	
	
	    //输出
		for (auto& x : ver)cout << x;

	return 0;
}

image.png