1. Title Description
Xiao Ming had a long and long dream. When he woke up, he found himself and his friends on a crumbling chessboard. They had to do everything possible to escape from here.
After a long exploration, Xiaoming found that there was an organ on the board grid where he was located, which said "You only have one chance, the door will open for you in t seconds after departure", and the board where he is located is N * M's rectangle, he can move up, down, left, and right (no obstacles). There is a door in the board.
According to the government's prompt, Xiao Ming suddenly understood that he and his friend must arrive at the door in the tth second. And all this, there is no turning back! Because once he moves, the point he was at will disappear, and he cannot stay on a point for more than one second, otherwise the grid will explode.
The big escape has begun, can Xiaoming and his friends safely escape this strange chessboard?
Input
Enter multiple sets of test data. The first line of each test case contains three integers N, M, and T (1 <N, M <7; 0 <T <50), indicating the size of the chessboard and the time the door is open. The next N lines give the board layout, each line contains M characters. among them
- ".": Barrier-free point
"X": Obstacle point
"S": Starting point
"D": Door
The input ends with 3 zeros. This test case does not need to be processed.
Output
One line is output for each set of samples.
If Xiaoming can escape safely, output "YES", otherwise output "NO".
Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
Sample Output
NO
YES
Second, the solution
Method 1: dfs search
- Regular dfs can only get 30pt.
- Small pruning: When reach = true, there is no need to continue searching.
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static int N, M, T;
static int sx, sy, ex, ey;
static char[][] grid;
final static int[][] dir = { {0,1},{0,-1},{1,0},{-1,0} };
static boolean[][] vis;
static boolean reach;
static boolean inArea(int x, int y) {
return x >= 0 && x < N && y >= 0 && y < M;
}
static void dfs(int x, int y, int t) {
if (grid[x][y] == 'D') {
reach = t == T;
return;
}
if (reach) return;
for (int k = 0; k < 4; k++) {
int tx = x + dir[k][0];
int ty = y + dir[k][1];
if (!inArea(tx, ty) || grid[tx][ty] == 'X' || vis[tx][ty])
continue;
vis[tx][ty] = true;
dfs(tx, ty, t+1);
vis[tx][ty] = false;
}
}
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
while (true) {
N = sc.nextInt();
M = sc.nextInt();
T = sc.nextInt();
if (N == 0 && M == 0 && T == 0)
break;
vis = new boolean[N][M];
grid = new char[N][M];
for (int i = 0; i < N; i++) {
String s = sc.next();
for (int j = 0; j < M; j++) {
grid[i][j] = s.charAt(j);
if (grid[i][j] == 'S') {
sx = i; sy = j;
} else if (grid[i][j] == 'D') {
ex = i; ey = j;
}
}
}
vis[sx][sy] = true;
dfs(sx, sy, 0);
System.out.println(reach ? "YES" : "NO");
reach = false;
}
}
}
Places for pruning:
- Pre-pruning : the current position
(x, y)
, the current number of steps to go, compared with:T-t
while the shortest distance between two points, also known as Manhattan distance wasabs(sx-ex) + abs(sy-ey)
, so whenT-t < abs(sx-ex) + abs(sy-ey)
the time3 3 4 S X X . X X X . D 在这里n*m-obs = 3*3-5 = 4 = t,故不可达
- Odd and even pruning :
Complexity analysis
- time complexity: , Note: Backtracking problems are generally not linear in complexity.
- Space complexity: ,
Method 2: bfs
This is a wrong choice, because the bfs must report the shortest path, and the shortest path is not necessarily the required time T.
Reference blog: https://blog.csdn.net/nvliba/article/details/48532709, with pictures and no code
10 like
text explanation
Evaluation address: https://vijos.org/d/orina_personal/p/5c4f2bf0f41362860e389f83