ACM选修课4 高精度

高精度算法

stirling公式:n!~ (n/e)n(2*pai*n)1/2^ (n趋向正无穷成立 当n大于100时可用)

例题

初等算数

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long int a,b;
    while(cin>>a>>b)
    {
        if(a==0&&b==0)
            break;
        int res=0;
        int c=0;
        for(int i=0; i<10; i++)
        {
            if(a%10+b%10+c>=10)
                res++,c=1;
            else
                c=0;
            a=a/10,b=b/10;
        }
        if(res==0)
            cout<<"No carry operation."<<endl;
        else if(res==1)
            cout<<"1 carry operation."<<endl;
        else
            cout<<res<<" carry operations."<<endl;
    }
    return 0;
}

计算N!

#include <bits/stdc++.h>
using namespace std;
const int maxn=50000;
int n,c,k;
int f[maxn+1];
int main()
{
    int n;
    while(cin>>n)
    {
        memset(f,0,sizeof(f));
        f[0]=1;
        for (int i=1; i<=n; i++)
        {
            c=0;
            for(int j=0; j<=maxn; j++)
            {
                int s=f[j]*i+c;
                f[j]=s%10;
                c=s/10;
            }
        }
        for(k=maxn; k>=0; k--)
            if (f[k]!=0)
                break;
        for(int j=k; j>=0; j--)
            cout<<f[j];
        cout<<endl;
    }
    return 0;
}

能不能更快一些:
发现f[i]里面的值只有1个数字,但f[i]是INT型啊,能存9位数啊,利用一下。
int s=f[j]*i+c;
f[j]=s%100000;//好好看看
c=s/100000;//每5位数字再进位
这回数组f开20000就够了,时间也快了~

for(k=maxn; k>=0; k--)
    if (f[k]!=0)
        break;
printf("%d",f[k]);
for(int j=k-1; j>=0; j--)
    printf(%05d”,f[j]);//5位的数字,不足前面添0
printf("\n");

还能不能更快:先计算N!的位数

#include <bits/stdc++.h>
using namespace std;
int a[40000];
int main()
{
    int n,k,l;
    double wei;
    while(cin>>n)
    {
        memset(a,0,sizeof(a));
        a[0]=1;
        wei=0;
        for(int i=1; i<=n; i++)
        {
            int c=0;
            wei+=log10(i);
            k=((int)wei+1)/5;
            for(int j=0; j<=k; j++)
            {
                int s=a[j]*i+c;
                a[j]=s%100000;
                c=s/100000;
            }
        }
        for(k=wei; k>=0; k--)
            if(a[k]!=0)
                break;
        printf("%d",a[k]);
        k--;
        for(k; k>=0; k--)
            printf("%05d",a[k]);
        printf("\n");
    }
    return 0;
}

不能白学高精度

#include <bits/stdc++.h>
using namespace std;
int a[50005],b[50005],ans[50005],n,nn;
void fibo()
{
    a[1]=1,b[1]=2;
    for(int i=3; i<=n; i++)
    {
        //表示增加的次数
        for(int j=1; j<=nn; j++)
            ans[j]=a[j]+b[j];
        for(int j=1; j<=nn; j++)
        {
            if(ans[j]>9)
            {
                ans[j+1]+=ans[j]/10;
                ans[j]%=10;
                if(j==nn)
                    nn++;
            }
        }
        for(int j=1; j<=nn; j++)
            a[j]=b[j];
        for(int j=1; j<=nn; j++)
            b[j]=ans[j];
    }
}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(ans,0,sizeof(ans));
        nn=1;
        if(n<3)
            printf("%d",n);
        else
        {
            fibo();
            for(int i=nn; i>0; i--)
                printf("%d",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_46126537/article/details/105420226