卡特兰数大数相乘

计算1-100卡特兰数,必须要用数组存,大数模板

注:
卡特兰数:卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列。由以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名。
原理:
   令h(1)=1,h(0)=1,catalan数满足递归式:   h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (其中n>=2)   另类递归式:   h(n)=((4*n-2)/(n+1))*h(n-1);   该递推关系的解为:   h(n)=C(2n,n)/(n+1) (n=1,2,3,...)
卡特兰数的应用:实质上都是递归等式的应用

 

C - Train Problem II
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

As we all know the Train Problem I, the boss of the Ignatius Train Station want to know if all the trains come in strict-increasing order, how many orders that all the trains can get out of the railway.
 

Input

The input contains several test cases. Each test cases consists of a number N(1<=N<=100). The input is terminated by the end of file.
 

Output

For each test case, you should output how many ways that all the trains can get out of the railway.
 

Sample Input

1 2 3 10
 

Sample Output

1 2 5 16796

Hint

 The result will be very large, so you may not process it by 32-bit integers. 


 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<math.h>
 5 #include<queue>
 6 #include<algorithm>
 7 using namespace std;
 8 int num[105][105];
 9 int b[105];
10 void catalan()
11 {
12     int i,j,carry=0,temp=0,length;
13     num[1][0]=1;length=1;b[1]=1;
14     for(i=2;i<=100;i++)
15     {
16         for(j=0;j<length;j++)//拷贝上一组数字
17         {
18             num[i][j]=num[i-1][j]*(4*i-2);
19         }
20         carry=0;
21         for(j=0;j<length;j++)//乘法
22         {
23              temp=carry+num[i][j];
24              num[i][j]=temp%10;
25              carry=temp/10;
26         }
27         while(carry)//还有进位
28         {
29             num[i][length++]=carry%10;
30             carry/=10;
31         }
32         carry=0;
33         for(j=length-1;j>=0;j--)//除法,从高位
34         {
35             temp=carry*10+num[i][j];
36             num[i][j]=temp/(i+1);
37             carry=temp%(i+1);
38         }//肯定不会有借位到0的,都是整数
39         while(!num[i][length-1])
40         {
41             length--;
42         }
43         b[i]=length;
44     }
45 }
46 int main()
47 {
48     int n,i;
49     catalan();
50     while(scanf("%d",&n)!=EOF)
51     {
52         for(i=b[n]-1;i>=0;i--)
53         {
54             printf("%d",num[n][i]);
55         }
56         printf("\n");
57     }
58 return 0;
59 }

 

这是比较简单的base是10的下附另外一种代码

 

 1     //输出卡特兰数   
 2     //首先需要肯定,程序是正确的   
 3     //这算是大数乘除法!记住他们是如何处理的!由于数据很大,用基本数据类型根本无法满足要求,只能用数组来表示!  
 4     #include <iostream>  
 5     #include<cstdio>  
 6     #include<memory.h>  
 7     using namespace std;  
 8     #define MAX 101  
 9     #define BASE 10000//base只是一个基度,对最终取值并没有影响,相反,base取值愈大,计算量愈小  
10     //base发生改变的时候,下面的输出也要相应地做出调整,否则也会输出错误答案!除非当base取10!  
11     void multiply(int a[],int len,int b)//乘法   
12     {  
13         for(int i=len-1,carry=0;i>=0;--i)//从最后一位开始相乘,依次向前与每一位相乘   
14         {//问题在于,为什么BASE=10000?   
15             carry+=b*a[i];  
16             a[i]=carry%BASE;  
17             carry/=BASE;  
18         //cout<<"carry="<<carry<<" "<<"a["<<i<<"]="<<a[i]<<endl;//以4个0为一组  
19         }   
20     }  
21     void divide(int a[],int len,int b)//除法,很妙的!这种除法可能想不到,仔细体会!   
22     {//应当如何除呢?  
23         for(int i=0,div=0;i<len;++i)//从高位除起  
24         {  
25             div=div*BASE+a[i];  
26             a[i]=div/b;//b为除数  
27             div%=b;  
28         }  
29     }  
30     int main()  
31     {  
32         int i,j,h[101][MAX];  
33         memset(h[1],0,MAX*sizeof(int));//赋值,每一个都置为0   
34         for(i=2,h[1][MAX-1]=1;i<=100;++i)//运用递归,并且h[1]=1;   
35         {  
36             memcpy(h[i],h[i-1],MAX*sizeof(int));//h[i]=h[i-1];按字节拷贝,保证了h[i]和h[i-1]指向数组的一致性   
37             multiply(h[i],MAX,4*i-2);//h[i]*=(4*i-2);  
38             divide(h[i],MAX,i+1);//h[i]/=(i+1);          
39         }//递归得到前100项的卡特兰数!  
40         while(cin>>i && i>=1 && i<=100)//输入i的值   
41         {  
42                     // for(i=1;i<=100;i++)  
43                     // {  
44             for(j=0;j<MAX && h[i][j]==0;++j);//从0位开始搜索,找到不为0的第一个数   
45             //printf("%d\n",EOF);在c语言中,EOF=-1;  
46             printf("%d",h[i][j++]);//像是这个输出,就很妙了,第一位可能不足四位,就地输出!  
47                   for(;j<MAX;++j)  
48             {  
49             //  if(h[i][j]==0)  
50             printf("%04d",h[i][j]);//处在中间的值也可能没有四位,这时候要注意了,往左边加0,凑足4位,不然答案会出错!  
51                 //  else  
52              // printf("%d",h[i][j]);//不断输出值   
53               
54            }  
55           
56             printf("\n");  
57         }  
58         system("pause");  
59           
60         return 0;  
61     }  

 

posted @ 2015-04-30 21:12  kingofprank  阅读(252)  评论(0编辑  收藏  举报