一、题目描述
给定一个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;
}
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,