POJ 2084 Game of Connections(大數+卡特蘭數)

Game of Connections
Time Limit: 1000MS

Memory Limit: 30000K
Total Submissions: 8331

Accepted: 4141

Description

This is a small but ancient game. You are supposed to write down the numbers 1, 2, 3, . . . , 2n - 1, 2n consecutively in clockwise order on the ground to form a circle, and then, to draw some straight line segments to connect them into number pairs. Every number must be connected to exactly one another. 
And, no two segments are allowed to intersect. 
It's still a simple game, isn't it? But after you've written down the 2n numbers, can you tell me in how many different ways can you connect the numbers into pairs? Life is harder, right?

Input

Each line of the input file will be a single positive number n, except the last line, which is a number -1. 
You may assume that 1 <= n <= 100.

Output

For each n, print in a single line the number of ways to connect the 2n numbers into pairs.

Sample Input

2
3
-1

Sample Output

2
題意:輸入一個n,將1-2n按順時針寫下來,任選兩個數用連線連接,要求連線不能交叉,且每個點只能連一次,
比如,n=2時,如圖,只有倆種情況,

思路:當n=3時,先考慮第一個點可以和哪個點相連,可以和2,4,6點相連,爲什麼3,5不行,因爲如果和第三個點相連,那麼第二個點無論和誰連都會出現交叉(如圖),與5不能相連的原因也是這樣,總結是如果連線的一邊的點的數量是奇數,那麼肯定不能兩兩連接,按照這種規律可以推出前幾項,a[1]=1,a[2]=2,a[3]=5,a[4]=14,,,滿足卡特蘭數的規律,根據卡特蘭數的遞推式a[i]=a[i-1]*(4*i-2)/(i+1);但這裏的乘除都是大數的乘除,,,
        利用萬進制的思想。。。。用二維數組打表。

以下AC代碼:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int max=100;
void mul(int a[],int b)
{///大數乘法
    int i,jinwei=0;///進位
    for(i=max-1;i>=0;i--)
    {
        jinwei+=b*a[i];
        a[i]=jinwei%10000;
        jinwei/=10000;
    }
}
void div(int a[],int b)
{///大數除法
    int i,jiewei=0;///借位
    for(i=0;i<max;i++)
    {
        jiewei=jiewei*10000+a[i];
        a[i]=jiewei/b;
        jiewei%=b;
    }
}
int main()
{
    int n;
    int i,j;
    int a[101][101];
    for(i=0;i<101;i++)
        for(j=0;j<101;j++)
        a[i][j]=0;
        ///初始化a[1]=1;
        for(i=0;i<max-1;i++)
            a[1][i]=0;
        a[1][max-1]=1;

    for(i=2;i<=100;i++)
    {
        memcpy(a[i],a[i-1],max*sizeof(int)); //將a[i-1]拷貝到a[i]
        mul(a[i],4*i-2);
        div(a[i],i+1);
    }
    while(scanf("%d",&n))
    {
        if(n==-1)
            break;
         for(i=0;i<max&&a[n][i]==0;i++);
            printf("%d",a[n][i++]);    ///輸出首位
            for(;i<max;i++)
                {
                    printf("%04d",a[n][i]);///輸出剩下的位數,數組中不足4位的在前邊補0
                }
                printf("\n");
    }

    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章