当前点到目标点的路径数量就是:右边的点到目标点的路径数量+下面的点到目标点的路径数量,依次类推,直到目标点。
由于我们是知道目标点位置的,所以直接从目标点开始,依次计算节点到目标节点的路径数量,赋值完成后起点(0,0)的值就是题目的解。
以下为核心代码:
public static void getPathPro(long[][] map,int aim_x,int aim_y){
for(int i=aim_x;i>=0;i--){
for(int j=aim_y;j>=0;j--){
if(map[i][j]>=0){
if(map[i+1][j]>=0){
map[i][j]+=map[i+1][j];
}
if(map[i][j+1]>=0){
map[i][j]+=map[i][j+1];
}
}
}
}
}
为了运行操作的一致性,在初始化数组时,若目标点为(n,m)则初始化的数组为long[n+1][m+1](由于最右边节的一列节点没有右节点,最下面一行的节点没有下面的节点)。
Scanner scanner=new Scanner(System.in);
//目标点位置
int aim_x=scanner.nextInt();
int aim_y=scanner.nextInt();
//马的位置
int horse_x=scanner.nextInt();
int horse_y=scanner.nextInt();
//用于描述棋盘的数组
long[][] map=new long[aim_x+2][aim_y+2];
int[]step=new int[]{1,2,-1,-2};
int[] xDirection=new int[4];
int[] yDirection=new int[4];
//存储马的向右及向下所能到达的单维度的值
for(int i=0;i<=3;i++){
xDirection[i]=horse_x+step[i];
yDirection[i]=horse_y+step[i];
}
//为马的控制点赋值(-1)
for(int i=0;i<=3;i++){
for(int j=0;j<=3;j++) {
if(xDirection[i]>=0&&yDirection[j]>=0){
//if条件用于防止出现右方向和下方向同时加正负1和正负2的情况,从而正确得到马的控制点
if(i%2!=j%2){
if(xDirection[i]<=aim_x&&yDirection[j]<=aim_y){
}
map[xDirection[i]][yDirection[j]]=-1;
}
}
}
}
//为马所在点赋值(-1)
map[horse_x][horse_y]=-1;
//为目标点下方的点(或者右方的点也可)赋值(1)
map[aim_x+1][aim_y]=1;
getPathPro(map,aim_x,aim_y);
System.out.println(map[0][0]);
public static void getPathPro(long[][] map,int aim_x,int aim_y){
for(int i=aim_x;i>=0;i--){
for(int j=aim_y;j>=0;j--){
if(map[i][j]>=0){
if(map[i+1][j]>=0){
map[i][j]+=map[i+1][j];
}
if(map[i][j+1]>=0){
map[i][j]+=map[i][j+1];
}
}
}
}
}
import java.util.Scanner;
public class P1002_SoliderCrossRiver {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
//目标点位置
int aim_x=scanner.nextInt();
int aim_y=scanner.nextInt();
//马的位置
int horse_x=scanner.nextInt();
int horse_y=scanner.nextInt();
//用于描述棋盘的数组
long[][] map=new long[aim_x+2][aim_y+2];
int[]step=new int[]{1,2,-1,-2};
int[] xDirection=new int[4];
int[] yDirection=new int[4];
//存储马的向右及向下所能到达的单维度的值
for(int i=0;i<=3;i++){
xDirection[i]=horse_x+step[i];
yDirection[i]=horse_y+step[i];
}
//为马的控制点赋值(-1)
for(int i=0;i<=3;i++){
for(int j=0;j<=3;j++) {
if(xDirection[i]>=0&&yDirection[j]>=0){
//if条件用于防止出现右方向和下方向同时加正负1和正负2的情况,从而正确得到马的控制点
if(i%2!=j%2){
if(xDirection[i]<=aim_x&&yDirection[j]<=aim_y){
}
map[xDirection[i]][yDirection[j]]=-1;
}
}
}
}
//为马所在点赋值(-1)
map[horse_x][horse_y]=-1;
//为目标点下方的点(或者右方的点)赋值(1)
map[aim_x+1][aim_y]=1;
getPathPro(map,aim_x,aim_y);
System.out.println(map[0][0]);
}
public static void getPathPro(long[][] map,int aim_x,int aim_y){
for(int i=aim_x;i>=0;i--){
for(int j=aim_y;j>=0;j--){
if(map[i][j]>=0){
if(map[i+1][j]>=0){
map[i][j]+=map[i+1][j];
}
if(map[i][j+1]>=0){
map[i][j]+=map[i][j+1];
}
}
}
}
}
}
在前日第一次做题时,使用的是简单暴力的递归方式,依次寻找点到目标点的路径,若目标点近时,还能到达答题要求,但是目标点远点则需要运行很久才能得到答案,且前日使用int类型回到的路径数量过大,溢出的情况,本次改用长整型long。这两天的独立思考,代码性能及解答都符合解题要求,也算是小小的进步。