题目大意: 给你2n个点要你在一个圈中连接任意两个点,而且直线不可相交。求直线数。1<=n<=100; 解题思路: 典型的catalan大数,输出h(n)即可,但是要做大数处理。 h(n)=(4n-2)/(n+1)*h(n-1)(n>1) h(0)=1 代码:
#include
using namespace std;
const int MAX_LEN = 10005;

int catalan[101][MAX_LEN];

void multip(int *ans, int b, int &len)
{
    int carry = 0;
    for(int j = 0; j < len; j++)
    {
        int temp = ans[j] * b + carry;
        ans[j] = temp % 10;
        carry = temp / 10;
    }
    while(carry)
    {
        len++;
        ans[len-1] = carry % 10;
        carry /= 10;
    }
}

void division(int *ans, int b, int &len)
{
    int r = 0;
    for(int i = len - 1; i >= 0; i--)
    {
        int temp = ans[i] + r * 10;
        ans[i] = temp / b;
        r = temp % b;
    }
    while(!ans[len-1])
    {
        len--;
    }
    return ;
}

int main(void)
{
    int len[101];
    memset(len, 0, sizeof(len));
    memset(catalan, 0, sizeof(catalan));
    catalan[0][0] = 1;//由catalan的0值开始产生
    len[0] = 1;
    for(int i = 1; i < 101; i++)
    {
        memcpy(catalan[i], catalan[i-1], MAX_LEN * sizeof(int));
        len[i] = len[i-1];//copy前面的

        multip(catalan[i], 4 * i - 2, len[i]);
        division(catalan[i], i + 1, len[i]);
    }
    /*for(int i = 0; i < 20; i++)
    {
    	for(int j = len[i]-1; j >= 0; j--)
    		printf("%d", catalan[i][j]);
    	printf("\n");
    }*/
    int n;
    while(scanf("%d", &n), n >= 0)
    {
        for(int i = len[n] - 1; i >= 0; i--)
        {
            printf("%d", catalan[n][i]);
        }
        printf("\n");
    }
    return 0;
}





posted on 2012-02-14 16:05  cchun  阅读(280)  评论(0编辑  收藏  举报