过河卒(递推和递归)
#include <iostream>
#include <cstdio>
using namespace std;
int d[25][25],n,m,cx,cy;
long long dp[25][25]; //d数组用来记录是不是控制点(“马点”),dp数组用来记录路径数
int dir[8][2]={{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}}; //二维方向数组(将“马点”全部标记为1)
//dp[n][m]就表示到坐标为(n,m)点的可能的路径总数
void fun()
{
d[cx][cy]=1; //马的初始位置(有马的地方标记为1)
for(int i=0;i<8;i++)
{
int tx=cx+dir[i][0];
int ty=cy+dir[i][1];
if(tx>=0 && tx<=n && ty>=0 && ty<=m) //注意范围
d[tx][ty]=1; //有马的地方标记为1
}
dp[0][0]=1; //不能把做这样的初始化:dp[1][0]=1; dp[0][1]=1;的原因在于:这两个点可能是“马点”
for(int i=0;i<=n;i++) //取等,因为需要算到坐标(n,m)
{
for(int j=0;j<=m;j++)//取等,因为需要算到坐标(n,m)
{
if(d[i][j]==0)//有马的地方不去(所以直接不算入)
{
if(i!=0 && j!=0)
dp[i][j]+=dp[i][j-1]+dp[i-1][j];//左边或者上边有马时,这一边过来的方法按0计算(所以这里直接加就行,因为数组的初始化是0)
if(i==0) //马只能往右或者往下
dp[i][j]+=dp[i][j-1]; //第一次循环时j-1是-1,没关系,反正dp初始化都是0
if(j==0)
dp[i][j]+=dp[i-1][j];
}
}
}
cout<<dp[n][m];
}
int main()
{
cin>>n>>m;
cin>>cx>>cy;
fun();
return 0;
}