catalan 卡特兰 卡塔兰 大数

/*

Cn = C(2n,n) / (n+1)

或者 Cn = (4*n - 2 ) *C(n-1)/(n+1);

或者 Cn = C(zn,n)-C(2n,n+1);


以下代码是将大数处理为一位一位的数,比如12345存储为a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4; a[4] = 4;

*/


#include <iostream>
#include <stdio.h>
#include <cmath>
using namespace std;

int a[103][105];    //大数卡特兰数 
int b[103];         //卡特兰数的长度

void catalan()  //求卡特兰数根据公式:c(n) = (4*n - 2)*c(n-1)/(n+1) 
{
    int i, j, len, carry, temp;
    a[1][0] = b[1] = 1;
    len = 1;
    for(i = 2; i <= 100; i++)
    {
        for(j = 0; j < len; j++)    //大数 乘法
            a[i][j] = a[i-1][j]*(4*i-2);
        carry = 0;      //此时carry 是余数 用来进位 
        for(j = 0; j < len; j++)    //处理相乘结果
        {
            temp = a[i][j] + carry;
            a[i][j] = temp % 10;
            carry = temp / 10;
        }
        while(carry)    //进位处理,讲一个大数拆分为一位一位的数字, 
        {                 // 如14拆分为,cl[0] = 1,cl[1] = 4;
            a[i][len++] = carry % 10;
            carry /= 10;
        }
        carry = 0;    // 此时carry 是余数 用来借位 
        for(j = len-1; j >= 0; j--) //除法
        {
            temp = carry*10 + a[i][j];
            a[i][j] = temp/(i+1);
            carry = temp%(i+1);
        }
        while(!a[i][len-1])     //高位零处理
            len--;
        b[i] = len;
    }
}
void Prin_catalan(int n)  //输出卡特兰数 
{
	for(int i = b[n]-1; i>=0; i--)
 	{
		printf("%d", a[n][i]);
  	}
} 
int main()
{
    int n;
    catalan();  //打表 
    while(scanf("%d", &n) != EOF)
    {
        Prin_catalan(n);
        printf("\n");
    }

    return 0;
}


你可能感兴趣的:(Catalan)