【题目大意】从文件中输入P(1000<P<3100000),计算的位数和最后500位数字(用十进制高精度数表示)
【思路】高精度+快速幂,代码实现有点烦,但至少比高精减要好。。。
对于位数,首先可以确定和
的位数一定是相同的。因为2的若干次方最后一位一定是大于0的。
考虑把的底数转化为10。因为
位数就是n+1。由于
那么可以把2替换成
,
就变成了
,那么位数就是
,代码写出来就是 int(log10(2)*p+1)。
#include<bits/stdc++.h>
#define re register
using namespace std;
int P,lena,lenb,ans;
int a[505],b[505];
void print(int x){
if(x>9) print(x/10);
putchar(x%10+'0');
}
void mul(int a[],int b[]){
int c[2000]={0};
lena=lenb=499;
for(int i=499;i>=0;i--) if(a[i]!=0){lena=i;break;}
for(int i=499;i>=0;i--) if(b[i]!=0){lenb=i;break;}
for(re int i=0;i<=lena;i++)
for(re int j=0;j<=lenb;++j){
c[i+j+1]+=a[i]*b[j]/10;
c[i+j]+=a[i]*b[j]%10;
}
for(re int i=0;i<=499;++i){
c[i+1]+=c[i]/10;
c[i]%=10;
}
for(re int i=499;i>=0;--i)
a[i]=c[i];
}
int main(){
a[0]=1,b[0]=2;
cin>>P;
printf("%d\n",int(log10(2)*P+1));
for(;P;P>>=1,mul(b,b)) if(P&1) mul(a,b);
a[0]-=1;
for(int h=1;h<=10;++h){
for(int i=499-(h-1)*50;i>=(500-h*50);i--)
putchar(a[i]+48);
putchar('\n');
}
return 0;
}