高精度運算(以Catalan數爲例)

大數加減乘除高精度運算在ACM比賽中很常用,以hdu1023卡特蘭數爲例,貼出兩份代碼以此爲模板,好好總結一下(Code真的很優雅~)。

// Catalan數
// 公式:h(n)=h(n-1)*(4*n-2)/(n+1)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Max=100;
const int Base=10000; // 萬進制(這個底數簡直超帥~)

int n;
int a[110][Max];

void multiply(int *a,int len,int b){ // 乘法
    int x=0;
    for(int i=len-1;i>=0;i--){
        x+=a[i]*b;
        a[i]=x%Base;
        x/=Base;
    }
}

void devide(int *a,int len,int b){ // 除法
    int x=0;
    for(int i=0;i<len;i++){
        x=x*Base+a[i];
        a[i]=x/b;
        x%=b;
    }
}

int main()
{
    memset(a,0,sizeof(a));
    a[1][Max-1]=1;
    for(int i=2;i<=100;i++){
        memcpy(a[i],a[i-1],sizeof(a[i-1]));
        multiply(a[i],Max,4*i-2);
        devide(a[i],Max,i+1);
    }
    while(~scanf("%d",&n)){
        int i;
        for(i=0;i<Max&&!a[n][i];i++); // 去掉開頭的0
        printf("%d",a[n][i++]);       // 輸出首個非0的數
        for(;i<Max;i++)
            printf("%04d",a[n][i]);   // 輸出後面的數
        putchar('\n');
    }
    return 0;
}

// Catalan數
// 公式:h(n)=h(n-1)*(4*n-2)/(n+1)
// 底數可換爲上面的萬進制,效率更高哦!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int main()
{
    int a[110][110],b[110];
    memset(a,0,sizeof(a));
    a[1][0]=1; // 低座標存放大數的低位
    b[1]=1;
    int len=1;
    for(int i=2;i<=100;i++){
        for(int j=0;j<len;j++)
            a[i][j]=a[i-1][j]*(4*i-2); // 模擬乘法,從低位開始
        int t=0;
        for(int j=0;j<len;j++){ // 處理相乘後的結果
            a[i][j]+=t;
            t=a[i][j]/10;
            a[i][j]%=10;
        }
        while(t){ // 進位處理
            a[i][len++]=t%10;
            t/=10;
        }
        t=0;
        for(int j=len-1;j>=0;j--){ // 模擬除法,從高位開始
            a[i][j]+=t*10;
            t=a[i][j]%(i+1);
            a[i][j]/=(i+1);
        }
        while(!a[i][len-1]) // 高位零處理
            len--;
        b[i]=len;
    }

    int n;
    while(cin>>n){
        for(int i=b[n]-1;i>=0;i--)
            cout<<a[n][i];
        cout<<endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章