大數加減乘除高精度運算在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;
}