问题描述
形如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的位数和最后500位数字(用十进制高精度数表示)
输入格式
文件中只包含一个整数P(1000<P<3100000)
输出格式
第一行:十进制高精度数2
P-1的位数。
第2-11行:十进制高精度数2 P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
不必验证2 P-1与P是否为素数。
第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
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");
}
}