问题标题: 洛谷:P1045 喜提WA+TLE,QwQ

0
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
褚俊皓
褚俊皓
新手天翼
新手天翼

11月前在第一页。。。

0
0
0
我要回答