这是我见过的最离谱的一道题.....
需要两次DFS+一次BFS
需要注意:
1.BFS记得Visit数组,对于访问过的节点,不要再加入到队列中,否则会内存溢出
2.DFS注意方向.以from-->to的方向为基准,标记好前后左右,再进行dfs.
以下是AC代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.StringTokenizer;
public class Main {
static boolean[][] isVisit;
static char[][] road;
static int ans, m, n;
static boolean hasAns;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int T = Integer.parseInt(st.nextToken());
for (int testcase = 1; testcase <= T; testcase++) {
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
isVisit = new boolean[m][n];
road = new char[m][n];
String s;
int startX = 0, startY = 0, endX = 0, endY = 0;
for (int i = 0; i < m; i++) {
s = br.readLine();
road[i] = s.toCharArray();
if (s.indexOf('S') != -1) {
startX = i;
startY = s.indexOf('S');
}
if (s.indexOf('E') != -1) {
endX = i;
endY = s.indexOf('S');
}
}
ans = 0;
hasAns = false;
dfs(startX, startY, 'u');
System.out.print(ans + " ");
ans = 0;
hasAns = false;
dfs2(startX, startY, 'u');
System.out.print(ans + " ");
ans = 0;
isVisit = new boolean[m][n];
bfs(startX, startY);
System.out.println(ans);
}
}
private static void dfs(int x, int y, char direct) {
ans++;
if(hasAns){
return;
}
if (road[x][y] == 'E') {
hasAns = true;
return;
}
if (direct == 'u') {
if (y - 1 >= 0 && road[x][y - 1] != '#') {
dfs(x, y - 1, 'l');
} else if (x - 1 >= 0 && road[x - 1][y] != '#') {
dfs(x - 1, y, 'u');
} else if (y + 1 < n && road[x][y + 1] != '#') {
dfs(x, y + 1, 'r');
} else if (x + 1 < m && road[x + 1][y] != '#') {
dfs(x + 1, y, 'd');
}
}
else if (direct == 'l') {
if (x + 1 < m && road[x + 1][y] != '#') {
dfs(x + 1, y, 'd');
} else if (y - 1 >= 0 && road[x][y - 1] != '#') {
dfs(x, y - 1, 'l');
} else if (x - 1 >= 0 && road[x - 1][y] != '#') {
dfs(x - 1, y, 'u');
} else if (y + 1 < n && road[x][y + 1] != '#') {
dfs(x, y + 1, 'r');
}
}
else if (direct == 'd') {
if (y + 1 < n && road[x][y + 1] != '#') {
dfs(x, y + 1, 'r');
} else if (x + 1 < m && road[x + 1][y] != '#') {
dfs(x + 1, y, 'd');
} else if (y - 1 >= 0 && road[x][y - 1] != '#') {
dfs(x, y - 1, 'l');
} else if (x - 1 >= 0 && road[x - 1][y] != '#') {
dfs(x - 1, y, 'u');
}
}
else if (direct == 'r') {
if (x - 1 >= 0 && road[x - 1][y] != '#') {
dfs(x - 1, y, 'u');
} else if (y + 1 < n && road[x][y + 1] != '#') {
dfs(x, y + 1, 'r');
} else if (x + 1 < m && road[x + 1][y] != '#') {
dfs(x + 1, y, 'd');
} else if (y - 1 >= 0 && road[x][y - 1] != '#') {
dfs(x, y - 1, 'l');
}
}
}
private static void dfs2(int x, int y, char direct) {
ans++;
if(hasAns){
return;
}
if (road[x][y] == 'E') {
hasAns = true;
return;
}
if (direct == 'u') {
if (y + 1 < n && road[x][y + 1] != '#') {
dfs2(x, y + 1, 'r');
} else if (x - 1 >= 0 && road[x - 1][y] != '#') {
dfs2(x - 1, y, 'u');
} else if (y - 1 >= 0 && road[x][y - 1] != '#') {
dfs2(x, y - 1, 'l');
} else if (x + 1 < m && road[x + 1][y] != '#') {
dfs2(x + 1, y, 'd');
}
}
else if (direct == 'l') {
if (x - 1 >= 0 && road[x - 1][y] != '#') {
dfs2(x - 1, y, 'u');
} else if (y - 1 >= 0 && road[x][y - 1] != '#') {
dfs2(x, y - 1, 'l');
} else if (x + 1 < m && road[x + 1][y] != '#') {
dfs2(x + 1, y, 'd');
} else if (y + 1 < n && road[x][y + 1] != '#') {
dfs2(x, y + 1, 'r');
}
}
else if (direct == 'd') {
if (y - 1 >= 0 && road[x][y - 1] != '#') {
dfs2(x, y - 1, 'l');
} else if (x + 1 < m && road[x + 1][y] != '#') {
dfs2(x + 1, y, 'd');
} else if (y + 1 < n && road[x][y + 1] != '#') {
dfs2(x, y + 1, 'r');
} else if (x - 1 >= 0 && road[x - 1][y] != '#') {
dfs2(x - 1, y, 'u');
}
}
else if (direct == 'r') {
if (x + 1 < m && road[x + 1][y] != '#') {
dfs2(x + 1, y, 'd');
} else if (y + 1 < n && road[x][y + 1] != '#') {
dfs2(x, y + 1, 'r');
} else if (x - 1 >= 0 && road[x - 1][y] != '#') {
dfs2(x - 1, y, 'u');
} else if (y - 1 >= 0 && road[x][y - 1] != '#') {
dfs2(x, y - 1, 'l');
}
}
}
private static void bfs(int xx, int yy) {
ArrayDeque next = new ArrayDeque();
next.addLast(new int[]{xx, yy, 1});
int[] poll;
int x, y, dist;
while (!next.isEmpty()) {
poll = next.pollFirst();
x = poll[0];
y = poll[1];
dist = poll[2];
if (road[x][y] == 'E') {
ans = dist;
return;
}
if(isVisit[x][y]){
continue;
}
isVisit[x][y] = true;
if (x + 1 < m && road[x + 1][y] != '#' && !isVisit[x + 1][y]) {
next.addLast(new int[]{x + 1, y, dist + 1});
}
if (y - 1 >= 0 && road[x][y - 1] != '#' && !isVisit[x][y - 1]) {
next.addLast(new int[]{x, y - 1, dist + 1});
}
if (x - 1 >= 0 && road[x - 1][y] != '#' && !isVisit[x - 1][y]) {
next.addLast(new int[]{x - 1, y, dist + 1});
}
if (y + 1 < n && road[x][y + 1] != '#' && !isVisit[x][y + 1]) {
next.addLast(new int[]{x, y + 1, dist + 1});
}
}
}
}