一、題目描述
給定一個m × n (m行, n列)的迷宮,迷宮中有兩個位置,gloria想從迷宮的一個位置走到另外一個位置,當然迷宮中有些地方是空地,gloria可以穿越,有些地方是障礙,她必須繞行,從迷宮的一個位置,只能走到與它相鄰的4個位置中,當然在行走過程中,gloria不能走到迷宮外面去。令人頭痛的是,gloria是個沒什麼方向感的人,因此,她在行走過程中,不能轉太多彎了,否則她會暈倒的。我們假定給定的兩個位置都是空地,初始時,gloria所面向的方向未定,她可以選擇4個方向的任何一個出發,而不算成一次轉彎。gloria能從一個位置走到另外一個位置嗎?
Input
- 第1行爲一個整數t (1 ≤ t ≤ 100),表示測試數據的個數,接下來爲t組測試數據,每組測試數據中,
- 第1行爲兩個整數m, n (1 ≤ m, n ≤ 100),分別表示迷宮的行數和列數,接下來m行,每行包括n個字符,其中字符’.‘表示該位置爲空地,字符’*'表示該位置爲障礙,輸入數據中只有這兩種字符,每組測試數據的最後一行爲5個整數k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能轉的彎數,(x1, y1), (x2, y2)表示兩個位置,其中x1,x2對應列,y1, y2對應行。
Output
- 每組測試數據對應爲一行,若gloria能從一個位置走到另外一個位置,輸出“yes”,否則輸出“no”。
Sample Input
2
5 5
...**
*.**.
.....
.....
*....
1 1 1 1 3
5 5
...**
*.**.
.....
.....
*....
2 1 1 1 3
Sample Output
no
yes
二、題解
題目大意:判斷能不能在限制拐彎數的情況下從起點走到終點。
方法一:bfs + 單方向窮舉
- 當枚舉某一個方向時,就繼續從這個方向走到底,換個方向之後也是這樣。
- 當有結點出隊時,之前的 4 個方向的點肯定被標記爲 visited 了,所以只能拐彎,這時把出隊的結點的拐彎數
cur.turn++
import java.util.*;
import java.math.*;
import java.io.*;
public class Main {
static int R, C;
static char[][] grid;
final static int[][] dir = { {0,1},{0,-1},{1,0},{-1,0} };
static boolean[][] vis;
private static boolean inArea(int x, int y) {
return x >= 0 && x < R && y >= 0 && y < C;
}
// public static void main(String[] args) throws IOException {
// Scanner sc = new Scanner(new BufferedInputStream(System.in));
// PrintWriter pw = new PrintWriter(System.out, true); //自動刷新
// int T = sc.nextInt();
// while (T-- > 0) {
// R = sc.nextInt();
// C = sc.nextInt();
// grid = new char[R][C];
// vis = new boolean[R][C];
// for (int i = 0; i < R; i++) {
// grid[i] = sc.next().toCharArray();
// int limit = sc.nextInt();
// int x1=sc.nextInt();
// int y1=sc.nextInt();
// int x2=sc.nextInt();
// int y2=sc.nextInt();
// System.out.println(bfs(x1, y1, x2, y2, limit) ? "yes" : "no");
// }
// }
// }
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
while(t-->0){
R=sc.nextInt();
C=sc.nextInt();
grid=new char[R][C];
vis=new boolean[R][C];
for(int i=0;i<R;i++){
grid[i]=sc.next().toCharArray();
}
int limit=sc.nextInt();
int y1=sc.nextInt();
int x1=sc.nextInt();
int y2=sc.nextInt();
int x2=sc.nextInt();
System.out.println(bfs(x1-1, y1-1, x2-1, y2-1, limit) ? "yes" : "no");
}
}
private static boolean bfs(int sx, int sy, int ex, int ey, int limit) {
Queue<Pos> q= new LinkedList<>();
q.add(new Pos(sx, sy, -1));
vis[sx][sy] = true;
while (!q.isEmpty()) {
Pos cur = q.poll();
if (cur.x == ex && cur.y == ey && cur.turn <= limit) {
return true;
}
cur.turn++;
for (int k = 0; k < 4; k++) {
int tx = cur.x + dir[k][0];
int ty = cur.y + dir[k][1];
while (inArea(tx, ty) && grid[tx][ty] != '*') {
if (!vis[tx][ty]) {
q.add(new Pos(tx, ty, cur.turn));
vis[tx][ty] = true;
}
tx += dir[k][0];
ty += dir[k][1];
}
}
}
return false;
}
static class Pos {
int x, y, turn;
public Pos(int _x, int _y, int _turn) {
x = _x;
y = _y;
turn = _turn;
}
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,