棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。棋盘用坐标表示,A点(0,0)、B点(n,m)(n,m为不超过15的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入:一行四个数据,用空格分隔,分别表示B点的坐标和马的坐标(6 6 3 3)。
输出:一个数据,表示所有的路径条数。(6)。
import java.util.Scanner;
public class soldier {
public static void main(String args[])throws Exception
{
Scanner src =new Scanner(System.in);
//定义棋盘数组和动态规划数组(测试数据较大,dp最好用long类型);
int [][]map=new int [21][21];
long [][]dp=new long [21][21];
//输入终点B的坐标和马的坐标;
int n=src.nextInt();
int m=src.nextInt();
int x=src.nextInt();
int y=src.nextInt();
//存放马的控制点坐标(以马为原点的相对位置);
int a[]= {0,1,1,-1,-1,2,2,-2,-2};
int b[]= {0,2,-2,2,-2,1,-1,1,-1};
//初始化地图,所有点都能通过;
for(int i=0;i<=20;i++)
for(int j=0;j<=20;j++)
{
map[i][j]=1;
}
//判断马的控制点是否在地图外,地图内的点标记为0;
for(int i=0;i<9;i++)
{
if(x+a[i]>=0&&x+a[i]<=20&&y+b[i]>=0&&y+b[i]<=20)
{
map[x+a[i]][y+b[i]]=0;
}
}
//因为士兵只能向右或向下出发,所以初始化第一行和第一列,赋值为1;
for(int i=0;i<=20;i++)
{
if(map[i][0]==1)
{
dp[i][0]=1;
}
else {
break;
}
}
for(int i=0;i<=20;i++)
{
if(map[0][i]==1)
{
dp[0][i]=1;
}
else {
break;
}
}
//状态方程递归到(n,m),通过解决子问题解决整体问题;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(map[i][j]==1)
{
dp[i][j]=dp[i][j-1]+dp[i-1][j];
}
}
System.out.println(dp[n][m]);
}
}
测试用例结果图:
![](https://img-blog.csdnimg.cn/direct/3e36aeface694b24a29e195eee18b12c.png)
AC测试图:
![](https://img-blog.csdnimg.cn/direct/8eee09b015e24cda8e9fed938b24e4ee.png)