小兔的棋盘
问题描述
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
解题思路
由题目的描述可知不能够穿越对角线,但是可以触碰对角线上的点。即可以在对角线上,但是不能够从对角线上的一端越到对角线的另一端
比如我在这
我可以这样
但是不能越过对角线即
因为棋盘是对称的,所以我们只需要算出上半部分或者下半部分再乘以二即可,以下解释均基于上半部分
其他路径均可以
这里棋盘用二维数组a[][]表示,
第一行的路径只能从左边传过来,故a[0][y]=1
其他路径均可以从上面和左边传过来a[x][y]=a[x-1][y]+a[x][y-1]
特别注意:当xy的时候,只能从上面传过来因为这是半个图形,所以当xy的时候
a[x][y]==a[x][y-1]
下面使用c++实现
#include<iostream>
using namespace std;
long long a[35][35];
void init(){
int i, j;
//第一列都等于1
for(i = 1; i <= 36; i++)
{
a[0][i] = 1;
}
for(i = 1; i < 36; i++)
{
//因为不能越过对角线所以从j=i开始循环
for(j = i; j <= 36; j++)
{
//相等的情况
if(i == j)
{
a[i][j] = a[i-1][j];
}
//不相等
else
{
a[i][j] =a[i-1][j] + a[i][j-1];
}
}
}
}
int main(){
//次数
int number=0;
//输入的数字
int input;
init();
init2();
while(cin>>input&&input!=-1){
cout<<number++<<" "<<input<<" "<<a[input][input]*2<<endl;
//cout<<number++<<" "<<input<<" "<<f[input][input]*2<<endl;
}
return 0;
}
运行结果