P1045 麦森数
题目描述
形如2^{P}-12
P
−1的素数称为麦森数,这时PP一定也是个素数。但反过来不一定,即如果PP是个素数,2^{P}-12
P
−1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
任务:从文件中输入PP(1000<P<31000001000<P<3100000),计算2^{P}-12
P
−1的位数和最后500位数字(用十进制高精度数表示)
输入格式:
文件中只包含一个整数PP(1000<P<31000001000<P<3100000)
输出格式:
第一行:十进制高精度数2^{P}-12
P
−1的位数。
第2-11行:十进制高精度数2^{P}-12
P
−1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
不必验证2^{P}-12
P
−1与PP是否为素数。
输入样例#1:
1279
输出样例#1:
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087
解题思路
分两问
第一问:利用数学公式–>(n*lg 2)+1
第二问:高精度快速幂,题目要求后500位,c++里应该没有什么数据类型可以保存,所以利用辅助数组,一样的利用快速幂的模板。思路大概就这样,迷糊的话,看代码就清楚了,分步做的QWQ。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
int a[1010],b[1010],s[1010];
void mss1()
{
memset(s,0,sizeof(s));
for(int i=1; i<=500; i++)
for(int j=1; j<=500; j++)//先乘后进位
s[i+j-1]+=a[i]*b[j];
for(int i=1; i<=500; i++)
{
s[i+1]+=s[i]/10;
s[i]%=10;
}
memcpy(a,s,sizeof(a));
}
void mss2() //更新幂
{
memset(s,0,sizeof(s));
for(int i=1; i<=500; i++)
for(int j=1; j<=500; j++)//先乘后进位
s[i+j-1]+=b[i]*b[j];
for(int i=1; i<=500; i++)
{
s[i+1]=s[i]/10;
s[i]%=10;
}
memcpy(b,s,sizeof(b));
}
int main()
{
int p;
cin>>p;
printf("%d\n",(int)(log10(2)*p+1));
a[1]=1;
b[1]=2;
while(p!=0)//开始快速幂
{
if(p%2==1) mss1();//由于有500位,所以使用辅助数组;
p=p/2;//就是p/2
mss2();//相当于2*2,4*2,8*2,由于p太大了,所以需要辅助数组来完成
}
a[1]-=1;
for(int i=500; i>=1; i--)
if(i!=500&&i%50==0) printf("\n%d",a[i]);
else printf("%d",a[i]);
return 0;
}
做作业的小学生路过,勿扰!!!