题目大意:计算2^P-1的位数和它的最后500位并输出。
1、计算位数:2^P-1的位数为[log10(2^P)]+1==[Plog10(2)]+1
2、计算最后500位:高精度预处理2^i,计算时将P分解成二进制形式,然后相乘,只保留500位
代码一:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#define N 126
using namespace std;
int ans[N],anspow[N];
void mult(int ans[],int anspow[])
{
int i,j;
int c[N];
memset(c,0,sizeof(c));
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
if(i+j<N)//超出500位的部分不计算
{
c[i+j]+=ans[j]*anspow[i];
}
}
for(j=0;j<N-1;j++)
{
if(c[j]>=10000)
{
c[j+1]+=c[j]/10000;//压4位
c[j]%=10000;
}
}
}
memcpy(ans,c,N*sizeof(int)); //复制函数
}
int main()
{
int P,i,j;
while(cin>>P)
{
memset(ans,0,sizeof(ans));
memset(anspow,0,sizeof(anspow));
printf("%d\n",(int)(P*log10(2)+1));
ans[0]=1;
anspow[0]=2;
/************关键部分计算2^P*******
2^p=(2^1)*(2^2)*(2^3)*(2^4)*(2^5)………………
简单说下:P=5 -----101(二进制)
p & 1 =1(最右边一位) -->>>ans=2 anspow=2
p>>1=110 anspow=2^2
p & 1 =0 此时表明2^3不存在 ans=2 anspow=2^4
p>>1=1
p & 1 =1 ------>>>>> ans=2^5
p>>1=0 ------结束
************************************/
while(P)
{
if( P & 1)
mult(ans,anspow);
P>>=1;
mult(anspow,anspow);
}
ans[0]--;//2^P的个位为2,4,6,8,故可以-1
/****************输出格式的控制************************/
for(i=124;i>=0;i--)
{
if(i%25==12)
{
printf("%02d\n%02d",ans[i]/100,ans[i]%100);
}
else
{
printf("%04d",ans[i]);
if(i%25==0) printf("\n");
}
}
/***************************************************/
}
return 0;
}
代码二:
/*************麦森数****************/
#include<iostream>
#include<cstdio>
#include<cmath>
#define N 100 //压5位
using namespace std;
int ans[N];
void mult(int t)
{
int i,temp,last=0;
for ( i=N-1; i>=0; i--)
{
temp=(ans[i]<<t)+last; //乘2^t,加进位
last=temp/100000;
ans[i]=temp-last*100000; //temp%100000
}
}
void output()
{
int i;
for(i=1;i<=N;i++)
{ printf("%05d",ans[i-1]);
if (i%10==0)cout<<endl;
}
}
int main()
{
int P,times;
while(cin>>P)
{
memset(ans,0,sizeof(ans));
ans[N-1]=1;
cout<<(int)(P*log10(2)+1)<<endl;
/***********************关键部分*****************
2^P=2^(14*times)*2^(P%14) 用移位
之所以取14的原因 2^14*(99999)=1.638382*10^9 在(int)
范围,15以后都会超int,主要体现在mult()中
**********************************************/
times=P/14; //只能到14 15以后压缩时会超范围
while(times--)
mult(14);
mult(P%14);
--ans[99];
output();
}
return 0;
}
转自:http://www.cnblogs.com/lsx54321/archive/2012/07/25/2608414.html