- 题目:n行m列的棋盘,有一些格子上有障碍物,从左上角出发,每次移动可以是以下三种方式的一种:
- 向右移动若干格子,(x+k,y)
- 向下移动若干格子,(x,y+k)
- 向右下移动若干格子,(x+k,y+k)
- 求:坐上到右下,最少移动多少步?
import java.util.*;
public class jd3 {
public static void main(String[] args) {
int[][] ob = {{0,0,0,0},{1,1,0,1},{0,0,0,0}};
int n = ob.length;
int m = ob[0].length;
if(ob[0][0]==1 || ob[n-1][m-1]==1) {
System.out.println(-1);
return;
}
int[][] dp = new int[n][m];
String[][] dir = new String[n][m];
dp[0][0] = 1;
dir[0][0] = "start";
for(int i=1;i<n;i++) {
if(ob[i][0]==1) dp[i][0]=-1;
else dp[i][0] = dp[i-1][0];
dir[i][0] = "u";
}
for(int j=1;j<m;j++){
if(ob[0][j]==1) dp[0][j]=-1;
else dp[0][j] = dp[0][j-1];
dir[0][j] = "l";
}
int u,l,ul;
for(int i=1;i<n;i++) {
for(int j=1;j<m;j++) {
if(ob[i][j]==1) dp[i][j] = -1;
else {
if(dp[i-1][j]!=-1 && dir[i-1][j].contains("u")) u = dp[i-1][j];
else if(dp[i-1][j]!=-1 && !dir[i-1][j].contains("u")) u = dp[i-1][j]+1;
else u=-1;
dp[i][j] = u;
dir[i][j]="u";
if(dp[i][j-1]!=-1 && dir[i][j-1].contains("l")) l = dp[i][j-1];
else if(dp[i][j-1]!=-1 && !dir[i][j-1].contains("l")) l = dp[i][j-1]+1;
else l=-1;
if(l!=-1) {
if(dp[i][j]==-1) {
dp[i][j]=l;
dir[i][j]="l";
}
else if(l<dp[i][j]) {
dp[i][j]=l;
dir[i][j]="l";
}else if(l==dp[i][j]) {
dir[i][j] += "l";
}
}
if(dp[i-1][j-1]!=-1 && dir[i-1][j-1].contains("o")) ul = dp[i-1][j-1];
else if(dp[i-1][j-1]!=-1 && !dir[i-1][j-1].contains("o")) ul = dp[i-1][j-1]+1;
else ul=-1;
if(ul!=-1) {
if(dp[i][j]==-1) {
dp[i][j]=ul;
dir[i][j]="o";
}
else if(ul<dp[i][j]) {
dp[i][j]=ul;
dir[i][j]="o";
}else if(ul==dp[i][j]) {
dir[i][j] += "o";
}
}
}
}
}
System.out.println("最短路径:"+dp[n-1][m-1]);
System.out.println("打印dp数组:");
for(int i=0;i<n;i++) {
System.out.println(Arrays.toString(dp[i]));
}
System.out.println("打印方向数组:");
for(int i=0;i<n;i++) {
System.out.println(Arrays.toString(dir[i]));
}
}
}
最短路径:2
打印dp数组:
[1, 1, 1, 1]
[-1, -1, 2, -1]
[-1, -1, 2, 2]
打印方向数组:
[start, l, l, l]
[u, null, uo, null]
[u, u, u, o]