Train ProblemII
Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7750 Accepted Submission(s): 4177
Problem Description
As we all know the TrainProblem I, the boss of the Ignatius Train Station want to know if all thetrains come in strict-increasing order, how many orders that all the trains canget out of the railway.
Input
The input contains severaltest cases. Each test cases consists of a number N(1<=N<=100). The inputis terminated by the end of file.
Output
For each test case, you shouldoutput 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-bitintegers.
Author
Ignatius.L
题目理解可以参考卡特兰数中常规非常规分析,总之就是求卡特兰数,因为题目要求计算到第100项,也就是最大位数快接近60位数,已经超过了长整型,就改用大数乘以int整型来计算
需要用到进位 carry,余数 div,百科里有算法。
用到公式 h(n)=h(n-1)*(4*n-2)/(n+1)
第一次接触到大数乘法,参考了别人的算法,比较好理解。
#include<stdio.h>
#include<string.h>
#define len 12
#define base 100000 //这里len和base随便符合要求就行,12*5>57
void multiply(int *a,int b)
{
for(int i=len-1,carry=0;i>=0;i--)
{
carry+=b*a[i];
a[i]=carry%base;
carry/=base;
}
}
void divide(int *a,int b)
{
for(int i=0,div=0;i<len;i++)
{
div=div*base+a[i];
a[i]=div/b;
div%=b;
}
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n)
{
int i,j=0,h[101][len];
memset(h[1],0,len*sizeof(int)); //一定要初始化,不然就郁闷了
for(i=2,h[1][len-1]=1;i<=n;i++)
{
memcpy(h[i],h[i-1],len*sizeof(int));
multiply(h[i],4*i-2);
divide(h[i],i+1);
}
while(h[n][j]==0)
{
j++;
}
printf("%d",h[n][j++]);
for(;j<len;j++)
printf("%05d",h[n][j]);
printf("\n");
}
return 0;
}