麦森数

问题描述
  形如2 P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2 P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
  任务:从文件中输入P(1000<P<3100000),计算2 P-1的位数和最后500位数字(用十进制高精度数表示)
输入格式
  文件中只包含一个整数P(1000<P<3100000)
输出格式
  第一行:十进制高精度数2 P-1的位数。
  第2-11行:十进制高精度数2 P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
  不必验证2 P-1与P是否为素数。
样例输入
1279
样例输出
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887

32958028878050869736186900714720710555703168729087

解题思路:

关于位数,对2^p取10的对数即可,虽说最后减了1,但是不会影响最后的位数,最终为p*log10(2)+1;

因为数值比较大,可以用一个数组存储,一位表示5位,这样100即可;

普通的乘法肯定要超时,我们可以借助位运算,一次左移10次,最终对于不足10次左移的再一位一位移即可;

#include<cstdio>
#include<math.h>
#include<cstring>
#define max 100000
int main()
{
	int p;
	scanf("%d",&p);
	printf("%d\n",(int)(p*log10(2))+1);
	int ans[110];
	memset(ans,0,sizeof(ans));
	ans[0]=1;
	int left=p%10;
	p/=10;
	for(int i=1;i<=p;i++)
	{
		for(int j=0;j<=100;j++)
		{
			ans[j]<<=10;
		}
		for(int j=0;j<=100;j++)
		{
			if(ans[j]>=max)
			{
				ans[j+1]+=ans[j]/max;
				ans[j]%=max;
			}
		}
	}
	for(int i=1;i<=left;i++)
	{
		for(int j=0;j<=100;j++)
		ans[j]<<=1;
		for(int j=0;j<=100;j++)
		{
			if(ans[j]>=max)
			{
				ans[j+1]+=ans[j]/max;
				ans[j]%=max;
			}
		}
	}
	ans[0]-=1;
	for(int i=1;i<100;i++)
	{
		if(ans[i-1]<0)
		{
			ans[i]-=1;
			ans[i-1]+=max;
		}
		else
		break;
	}
	for(int i=99;i>=0;i--)
	{
		printf("%05d",ans[i]);
		if((100-i)%10==0)
		printf("\n");
	}
}


  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值