#题目#
棋盘上 A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A AA 点 (0,0)、B点 (n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 A 点能够到达 B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 B点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
输入输出样例
输入 #1
6 6 3 3
输出 #1
6
说明/提示
对于 100%100% 的数据,1≤n,m≤20,0≤ 马的坐标 ≤20。
解析
分析棋盘上到每个点的路径数目,如下图所示:
第一行和第一列是增加的边界,所以路径为0
据此,我们可以得出一个迭代式的(x,y)=(x-1,y)+(x,y-1).
动态规划检查是否越界时我们可以将整个图向右下方移动一个单位,空出一行一列便于越界检查。
象棋中马的走法是固定的(即马走日字),我们可以遍历马的八种走法(主要越界检查)。将马可以走的位置设为零。
初始化迭代时设(1,0)处=1,通过使用迭代式算出每一个点从A点可以到达的路径数,(也可以设(0,1)处=1,道理是相同的).
迭代完成后b点坐标处得出的路径数即为A到B得路径数。
java代码:
import java.util.Scanner;
public class luogu1002 {
public static void main(String[] args) {
int row,col,x,y;
Scanner s=new Scanner(System.in);
row=s.nextInt();
col=s.nextInt();
x=s.nextInt();
y=s.nextInt();
row++;
col++;
x++;
y++;
//初始化网格状态
long[][] map=new long[row+1][col+1];
for(int i=1;i<=row;i++)
for(int j=1;j<=col;j++)
map[i][j]=-1;
// for(int i=0;i<=row;i++) {
// map[i][0]=0;
// }
// for(int j=0;j<=col;j++) {
// map[0][j]=0;
// }
map[1][1]=1;
//马及马踏点置0
map[x][y]=0;
for(int i=-1;i<=1;i+=2) {
if(x+1*i>0&&x+1*i<=row)
for(int j=-1;j<=1;j+=2) {
if(y+2*j>0&&y+2*j<=col)
map[x+1*i][y+2*j]=0;
}
}
for(int i=-1;i<=1;i+=2) {
if(x+2*i>0&&x+2*i<=row)
for(int j=-1;j<=1;j+=2) {
if(y+1*j>0&&y+1*j<=col)
map[x+2*i][y+1*j]=0;
}
}
// //显示网格状态
// for(int i=0;i<=row;i++) {
// for(int j=0;j<=col;j++) {
// System.out.printf("%3d ", map[i][j]);
// }
// System.out.println();
// }
//
// System.out.println("------------------------------");
for(int i=1;i<=row;i++) {
for(int j=1;j<=col;j++) {
if(map[i][j]==-1)
map[i][j]=map[i-1][j]+map[i][j-1];
}
}
// //显示网格状态
// for(int i=0;i<=row;i++) {
// for(int j=0;j<=col;j++) {
// System.out.printf("%3d ", map[i][j]);
// }
// System.out.println();
// }
System.out.println(map[row][col]);
}
}
tip:注意数组数据类型,对于测试数据,数组使用int类型会溢出,(洛谷有两个测试项不通过),需使用long类型。