小兔的棋盘
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8690 Accepted Submission(s):
4548
Problem Description
小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!
Input
每次输入一个数n(1<=n<=35),当n等于-1时结束输入。
Output
对于每个输入数据输出路径数,具体格式看Sample。
Sample Input
1
3
12
-1
Sample Output
1 1 2
2 3 10
3 12 416024
Author
Rabbit
Source
Recommend
一个数学定理,详见博客 http://www.cnblogs.com/pshw/p/5325095.html
至于为什么是这个定理,参考网上大牛的想法
题目分析:为什么这个题要用卡特兰数呢?因为它的过程可以抽象成前例的样子,比如说先往下走,在往下走了一步的情况下,就可以往右走一步,这样向下走就等同于进栈,向右走就等同于出栈,有了卡特兰数的知识,这题就相当水了。(别忘了最后要乘2啊,因为只要满足不穿过对角线的话,先往下和先往右都可以的)
题意:中文题,很好理解,说一下输出,第一个数字是数据的组数,第二个数是输入的数,第三个则是路径数。
附上代码:
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 __int64 catalan[40]; 5 void catalans() 6 { 7 memset(catalan,0,sizeof(catalan)); 8 catalan[0]= catalan[1]= 1; 9 for(int i=2; i<= 35; i++) 10 { 11 for(int j=0; j< i; j++) 12 catalan[i]+=catalan[j]*catalan[i-j-1]; 13 } 14 } 15 int main() 16 { 17 int i,j,n,m; 18 int t=1; 19 catalans(); 20 while(cin>>n) 21 { 22 if(n==-1) 23 break; 24 cout<<t++<<" "<<n<<" "<<catalan[n]*2<<endl; 25 } 26 }