其实这道题如果你会递推,搞清楚问题的本质就很简单了
首先我们要知道加法原理,加法原理是什么呢?举个栗子:如果我们去上海只可以坐火车,坐飞机。而火车有n班次,飞机有m班次。那么总共去上海就有(n+m)种方式。
之后,我们就可以推出这个题目的递推表达式:
(ps:我们用f(x)(y)的形式来表示到达点(x,y)的步数。而且设g(n)(m)=1为马的的位置,那么马可能走到的位置(包括马的初始位置)为:)
> g[n][m];
g[n-2][m+1];
g[n-1][m+2];
g[n-2][m-1];
g[n-1][m-2];
g[n+1][m-2];
g[n+2][m-1];
g[n+2][m+1];
g[n+1][m+2];
1.如果终点在马的控制点(即马能走到得位置),毫无疑问步数为02.如果马的终点不在马的控制点上,那么步数就是所有上一步的步数之和,即 f(x)(y)=f(x-1)(y)+f(x)(y-1)(x,y为坐标)。但此处还有两种特殊情况:
-
一种是刚好x等于0,那么f(x)(y)=f(x)(y-1)(因为马只能向y轴方向移动,所以上一个位置只能为(x,y-1) )
- 一种是刚好y等于0,那么f(x)(y)=f(x-1)(y)(因为马只能向x轴方向移动,所以上一个位置只能为(x-1,y))
3.最后我们要设置起点f(0)(0)=1;
所以综上,我们可以写出程序
#include <iostream>
#include <cstdio>
using namespace std;
long long map[25][25];
int g[25][25];//g[i][j]==1为马的控制点
int main(){
int a,b,n,m;//(a,b)为b的坐标,(n,m)为马的坐标
cin>>a>>b>>n>>m;
//马的控制点
g[n][m]=1;
g[n-2][m+1]=1;
g[n-1][m+2]=1;
g[n-2][m-1]=1;
g[n-1][m-2]=1;
g[n+1][m-2]=1;
g[n+2][m-1]=1;
g[n+2][m+1]=1;
g[n+1][m+2]=1;
for (int i=0;i<=a;i++){
for (int j=0;j<=b;j++){
if (g[i][j]==1){
map[i][j]=0;
}else{ //如果不在马的控制点上
if (i==0&&j==0){
map[i][j]=1;//如果在起点
continue;//这个很重要,因为判断出一种结果后就要判断下一位置了
}
if (i==0) {
map[i][j]=map[i][j-1];
continue;
}
if (j==0){
map[i][j]=map[i-1][j];
continue;
}
map[i][j]=map[i][j-1]+map[i-1][j];
}
}
}
cout<<map[a][b];
return 0;
}