一、题目描述
-
总时间限制:
- 1000ms 内存限制:
- 65536kB
-
描述
-
有一个方格矩阵,矩阵边界在无穷远处。我们做如下假设:
a. 每走一步时,只能从当前方格移动一格,走到某个相邻的方格上;
b. 走过的格子立即塌陷无法再走第二次;
c. 只能向北、东、西三个方向走;
请问:如果允许在方格矩阵上走n步,共有多少种不同的方案。2种走法只要有一步不一样,即被认为是不同的方案。
输入
- 允许在方格上行走的步数n(n <= 20) 输出
- 计算出的方案数量 样例输入
样例输出
7
二、分析
一道可以用递归来解决的题目。题目要求:“只能向北、东、西三个方向走”,所以可以写3个if,但是走东、西方向之后,可以走的路径是相同的,所以可以只写2个if。
int f(int n,int o)//n为能走的步数,o为标志物(1为向北走,0为向东、西走)。
{
if(o==1){//向北走
return f(n-1,0)+f(n-1,1)+f(n-1,0);//向北走之后可以走的方向的方案总数(继续向北走或向东、西走)
}
if(o==0){//向东、西走
return f(n-1,0)+f(n-1,1);//向东、西走之后走的方向的方案总数(继续向东、西走或向北走)
}
}
现在这个函数还不完整,还要写边界。
int f(int n,int o)
{
if(n==0) return 0;//边界
if(o==1){
return f(n-1,0)+f(n-1,1)+f(n-1,0);
}
if(o==0){
return f(n-1,0)+f(n-1,1);
}
}
再写计算步数的代码。
int f(int n,int o)
{
if(n==0) return 0;
if(o==1){
if(n==1)
sum+=3;//计算步数
return f(n-1,0)+f(n-1,1)+f(n-1,0);
}
if(o==0){
if(n==1)
sum+=2;//计算步数
return f(n-1,0)+f(n-1,1);
}
}
这道题比较简单,做起来没有那么费力,也可以用算法解决,但是用算法比较麻烦,个人建议用递归的方法。
再来看一道题:
-
总时间限制:
- 10000ms 单个测试点时间限制:
- 1000ms 内存限制:
- 131072kB
-
描述
-
从一个无限大的矩阵的中心点出发,一步只能向右走、向上走或向左走。恰好走N步且不经过已走的点
共有多少种走法?
输入
-
一个数字,代表N,N<=1000
输出
-
输出有多少方案,最后结果模12345
样例输入
2
样例输出
7
一看数据范围就知道递归会爆,还要超时,看来不得不用动态规划了,状态转移方程也很容易找,
状态转移方程:f[n]=f[n-1]*2+f[n-2];
代码:
#include<cstdio>
int f[1005]={1,3};
int main()
{
int i,n;
scanf("%d",&n);
for(i=2;i<=1005;i++){
f[i]=(f[i-1]*2+f[i-2])%12345;
}
printf("%d",f[n]);
}