题解 | #迷宫问题#
迷宫问题
https://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc
调了好长时间,不知道为何定义成中等的,这玩意儿要是能一两个小时之内调通的,都是高手啊。
import java.util.*;
import java.lang.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNext()) { // 注意 while 处理多个 case
int n = in.nextInt();
int m = in.nextInt();
int[][] t = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
t[i][j] = in.nextInt();
}
}
Stack<String> out = new Stack<>();//存放走过的正确路径,用来最后输出
Linju first = new Linju(0, 0, n - 1, m - 1);//定义第一个点对象,设置点坐标边界
LinkedList<String> pres = new LinkedList<>();//记忆已经走过的路径,包含走错的
LinkedList<Linju> lll = new LinkedList<>();//存放每个点的邻居,每前进一步清空给下个点用
Stack<Linju> jiedian = new Stack<>();//遇到一个分叉路口,纪录当前路口的点为节点,方便走错时返回来
out.add(first.zuobiao());
Linju now = first;
//若未到最后一个点,就一直走
while (!(now.x == n - 1 && now.y == m - 1) && t[now.x][now.y] == 0) {
pres.add(now.zuobiao());//把当前点加入记忆
//取当前点的上下左右邻居,若没有返回null
Linju r = now.right();
Linju l = now.left();
Linju d = now.down();
Linju u = now.up();
//判断这些邻居中哪些是下一步可以走的,存入邻居组
for (Linju i : new Linju[] {r, l, d, u}) {
if (i != null && t[i.x][i.y] == 0 && !pres.contains(i.zuobiao())) {
lll.add(i);
continue;
}
}
if(lll.size()>1){
jiedian.add(now);//标记分叉口的节点
}
if (lll.size() > 0) {//若存在可走的点,则选择一个去走
now = lll.get(0);
lll.clear();
out.add(now.zuobiao());
} else if (lll.size() == 0) {//若已无路可走,返回到最近的一个分叉口重新走
Linju prejie = jiedian.pop();
int jieind = out.indexOf(prejie.zuobiao());
for(int i=out.size()-1;i>jieind;i--){
out.pop();//处理掉走错的点
}
now = prejie;
}
}
//输出正确的路径
for (String s : out) {
System.out.println(s);
}
}
}
//将点封装成对象,用于取坐标及上下左右的邻居
public static class Linju {
int x = 0;
int y = 0;
int rb = 0;
int cb = 0;
Linju(int x, int y, int ri, int ci) {
this.x = x;
this.y = y;
this.rb = ri;
this.cb = ci;
}
String zuobiao() {
return String.format("(%d,%d)", this.x, this.y);
}
Linju right() {
if (this.y < this.cb) {
return new Linju(this.x, this.y + 1, this.rb, this.cb);
} else {
return null;
}
}
Linju left() {
if (this.y > 0) {
return new Linju(this.x, this.y - 1, this.rb, this.cb);
} else {
return null;
}
}
Linju down() {
if (this.x < this.rb) {
return new Linju(this.x + 1, this.y, this.rb, this.cb);
} else {
return null;
}
}
Linju up() {
if (this.x > 0) {
return new Linju(this.x - 1, this.y, this.rb, this.cb);
} else {
return null;
}
}
}
}
