棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。 棋盘用坐标表示,A点(0,0)、B点(n,m)(n,m为不超过15的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。

输入格式:

一行四个数据,用空格分隔,分别表示B点的坐标和马的坐标。

输出格式:

一个数据,表示所有的路径条数。

输入样例:

6 6 3 3

输出样例:

6​

#include<stdio.h>
int main()
{
int n,m,x,y,i,j;//要到达的点为(n,m),马的位置为(x,y)
scanf("%d %d %d %d",&n,&m,&x,&y);
int f[20][20];//f[i][j]表示到达点(x,y)的路径数目
int g[20][20]={0};//要记得初始化
g[x][y]=1;//表示此点为马的控制点,不能走
int dx[9]={0,-2,-1,1,2,2,1,-1,-2};//从马的位置可以横向移动的位移
int dy[9]={0,1,2,2,1,-1,-2,-2,-1};//从马的位置可以纵向移动的位置
for(i=1;i<9;i++)
{
if((x+dx[i]>=0)&&(x+dx[i]<=n)&&(y+dy[i]>=0)&&(y+dy[i]<=m))
{
g[x+dx[i]][y+dy[i]]=1;//这些点不能走
}
}
for(i=0;i<=n;i++)
{
for(j=0;j<=m;j++)
{
if(g[i][j]==1)
{
f[i][j]=0;//马控制的点不能走,所以到达这些点的路径数目为0
}
else if(i==0&&j==0)
{
f[i][j]=1;//从(0,0)到(0,0)的数目为1
}
else if(i!=0&&j==0)
{
f[i][j]=f[i-1][j];
}
else if(i==0&&j!=0)
{
f[i][j]=f[i][j-1];
}
else
{
f[i][j]=f[i-1][j]+f[i][j-1];//到达某一点的路径数目,等于到达其相邻的上点和左点的路径数目之和。
}
}
}
printf("%d\n",f[n][m]);
return 0;

}

学习了数据结构之后,还可以用DFS遍历:

#include<stdio.h>
#include<string.h>
int num,n,m;
int a[20][20];
void dfs(int x,int y)
{
if(x==n&&y==m)
{
num++;
return ;//满足符合到达B的条件
}
else if(x<=n&&y<=m)
{
if(a[x][y]==0)//是否为可以走到的位置
{
dfs(x+1,y);//向右走
dfs(x,y+1);//向下走
}
}
else
return ;//如果超过B点则返回终止这次遍历
}
int main()
{
int p,q;
memset(a,0,sizeof(a));//初始化数组a为0
scanf("%d %d %d %d",&n,&m,&p,&q);
a[p][q]=1;
a[p+2][q+1]=1;
a[p+2][q-1]=1;
a[p+1][q+2]=1;
a[p+1][q-2]=1;
a[p-2][q+1]=1;
a[p-2][q-1]=1;
a[p-1][q+2]=1;
a[p-1][q-2]=1;//这是马的9个控制地点
dfs(0,0);//从点(0,0)开始遍历
printf("%d",num);
}