0
#include<bits/stdc++.h>
#define maxn 1000005
using namespace std;
struct Bigint
{
int len,a[maxn];
Bigint(int x=0)
{
memset(a,0,sizeof(a));
for(len=1;x;len++)
a[len]=x%10,x/=10;
len--;
}
int &operator[](int i)
{
return a[i];
}
void flatten(int L)
{
len=L;
for(int i=1;i<=len;i++)
a[i+1]+=a[i]/10,a[i]%=10;
while(!a[len])
len--;
}
void print()
{
if(len<500)
{
int cnt=1;
for(int i=1;i<=500-len;i++)
{
cout<<0;
if(cnt%50==0)
cout<<endl;
cnt++;
}
for(int i=max(len,1);i>=1;i--)
{
cout<<a[i];
if(cnt%50==0)
cout<<endl;
cnt++;
}
}
else
{
int cnt=1;
for(int i=len;i>=len-500+1;i--)
{
cout<<a[i];
if(cnt%50==0)
cout<<endl;
cnt++;
}
}
}
};
Bigint operator+(Bigint a,Bigint b)
{
Bigint c;
int len=max(a.len,b.len);
for(int i=1;i<=len;i++)
c[i]+=a[i]+b[i];
c.flatten(len+1);
return c;
}
Bigint operator*(Bigint a,int b)
{
Bigint c;
int len=a.len;
for(int i=1;i<=len;i++)
c[i]+=a[i]*b;
c.flatten(len+11);
return c;
}
int n;
int main()
{
cin>>n;
Bigint fac(1);
for(int i=1;i<=n/20;i++)
fac=fac*(pow(2,20));
for(int i=1;i<=n%20;i++)
fac=fac*2;
fac=fac+(-1);
cout<<fac.len<<endl;
fac.print();
return 0;
}
主要是print有锅,求帮忙看看
0
0
0
0
0
0
0
让我们来分析一下题目,第一位是送分的,有一个专门求位数的函数:n*log10(2)+1。 然后题目中p<=3100000,又要求后500位,普通算法肯定超时,但如果我们多压几位甚至时间都比普通快速幂少。而且我们用 long long 的话可以一次就乘上2的20次方又能节省时间;
第一问:
s=n*log10(2)+1;用函数算位数
cout<<s<<endl;
第二问:算后500位:
while(n>=20){
k=0;
for(i=1;i<=50||i<=top;i++){//数组的每一个元素里放十位数
a[i]=a[i]*1048576+k;//每次乘上2的20次方:“1048576”把longlong剩余9位用到位
k=a[i]/ya;a[i]%=ya;//进位
if(top<50&&k&&i==top)top++;//加位数
}
n-=20;//一次算20个
}
注意:n<20时还需要还需要用一次乘2的循环!
小于500位要加前导零:
while(i<=50){//小于500位,要加前导零
for(j=1;j<=5&&i<=50;i++,j++)cout<<"0000000000";//补10个0
if(j==6)cout<<endl;
}
大于500位的情况:
while(i>=1){//注意:大于五百位也有可能有前导零
for(j=1;j<=5&&i>=1;i--,j++){//是每一个元素(10位)中的的前导零
if(a[i]>1000000000)cout<<a[i];//判断是否有前导零
else{
s=a[i];
while(s>0){s/=10;o++;}//记录前导零个数
o=10-o;
while(o>0){o--;cout<<"0";}//输出
cout<<a[i];
}
}
cout<<endl;
}
0
0
0
0