BFS求出最短距离,然后再逆序输出即可。
此题可以建模成一个无向无权网络,从起点开始最先搜索到的一定是到这个节点的最短距离。保存最短距离,此后再搜索到这个节点,必然不是最短距离,不用更新最短距离。
此题保证最短路径唯一,所以只需要从最后一个节点倒序搜索即可,只需要满足上一个节点的距离+1等于当前节点的距离,那么上一个节点必然是最短路径上的,保存到路径集合上,然后更新当前节点为上一个节点。
import java.util.*;
public class Main {
static int n, m;
static int[][] a;
static Map<Node, Integer> dist = new HashMap<>();
static int[] dx = new int[]{0,-1,0,1};
static int[] dy = new int[]{1,0,-1,0};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
a = new int[n][m];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
a[i][j] = sc.nextInt();
}
}
Node be = new Node(0,0);
Node en = new Node(n-1,m-1);
dist.put(be, 0);
Queue<Node> q = new LinkedList<>();
q.offer(be);
while(q.size() > 0) {
Node x = q.poll();
if(x.equals(en)) {
break;
}
for(int i = 0; i < 4; i++) {
int aa = x.x + dx[i], bb = x.y + dy[i];
if(aa >= 0 && aa < n && bb >= 0 && bb < m && a[aa][bb] == 0) {
Node ne = new Node(aa,bb);
if(dist.get(ne) == null) {
dist.put(ne, dist.get(x) + 1);
q.offer(ne);
}
}
}
}
List<Node> lst = new ArrayList<>();
lst.add(en);
Node now = en;
while(!now.equals(be)) {
for(int i = 0; i < 4; i++) {
int aa = now.x + dx[i], bb = now.y + dy[i];
if(aa >= 0 && aa < n && bb >= 0 && bb < m && a[aa][bb] == 0) {
Node ne = new Node(aa,bb);
if(dist.get(ne) != null && dist.get(ne) + 1 == dist.get(now)) {
lst.add(ne);
now = ne;
break;
}
}
}
}
for(int i = lst.size() - 1; i >= 0; i--) {
System.out.println("(" + lst.get(i).x + "," + lst.get(i).y + ")");
}
}
}
class Node {
int x, y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
public int hashCode() {
return 1 << x + y;
}
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(obj instanceof Node) {
Node node = (Node)obj;
return this.x == node.x && this.y == node.y;
}
return false;
}
}