铁轨出轨总数目(卡塔兰数及大数的运用)

 

个人心得:对于这种数学题,思路真的要很清晰,我开始的思路是假设n=1ton=n-1,出栈找规律,然后发现后面乱来乱复杂,完全没有数学之美的地方,

后面了解了卡塔兰数的思想发现数学家真是可怕的生物,n个数,必然都有可能出现在最后,假设k在最后,则有1到k-1出轨和k+1到n出轨,所以对每个数加就好了,

即f(n)=f(0)*f(n-1)+f(1)*f(n-2)...

所以以后还是要注意数学思维的实用性和规律性,非常规思想性

最后可以得出卡特兰数的推导式:cn=c(n-1)*(4*n-2)/(n+1)

这是就涉及到大数的乘除,这题中思想还是挺好的,具体看代码就知道了。

Train Problem II

Problem 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 //输出卡特兰数 
 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 @ 2017-07-31 10:32  余生漫漫浪  阅读(284)  评论(0编辑  收藏  举报