洛谷—P1045 麦森数(高精度)

在这里插入图片描述

这道题可以分为两个模块,第一个模块为求的位数,第二个模块为求的后500位(不足补零)。我们主要来解决第一个模块:

一、求位数

首先我们知道 与 有着相同的位数,因为2的次方满足了最后一位不为零的要求,所以减一后位数并不会改变,那么我们可以直接求 的位数。那么怎么求位数呢?我们不妨设 ,根据 的位数为 ,我们只要想办法把 中的底数2改为10,指数加一就是位数了。由此想到用10的几次方来代替2,那么就不难想到 ,这样便可以把 中的2代换掉,变为 。根据乘方的原理,将p乘进去,原式便可化为我们最终想要的形式 了,所以位数就是 。(提醒一下,C++中cmath库自带log10()函数…)

二、求最后500位数

这个绝对难不倒大家,裸的高精快速幂,经过NOIP2017初赛的RP++后,相信很多人都已经会了快速幂了,所以我在这里不再赘述,只是提供一种相对较为简便的高精乘法(见程序)

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
long long str[100000];
int main()
{
	int n,len=1;
	cin >> n;
	int s = n * log10(2) + 1;
	str[0] = 1;
	cout << s << endl;
	while (n != 0) {
		int z = 0, k;
		if (n >= 27)
		{
			k = 27;
			n -= 27;
		}
		else
		{
			k = n;
			n = 0;
		}
		long long f = pow(2, k);
		for (int j = 0; j <= len; ++j)
		{
			long long temp = f * str[j] + z;
			z = temp / 10;
			str[j] = temp % 10;
			if (j == len - 1 && z != 0&&len<500)++len;
		}
	}
	if (str[0] != 0) str[0] -= 1;
	else
	{
		str[0] = 9;
		str[1] -=1;
	}
	if (str[1] == '-1')
	{
		str[2] -= 1;
		str[1] = 9;
	}
	for (int i = 499, j = 0; i >= 0; --i, ++j)
	{
		cout << str[i];
		if (j == 49)
		{
			cout << endl;
			j = -1;
		}
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值