献给阿尔吉侬的花束
题目来源:《信息学奥赛一本通》
时间限制:(1000ms) 内存限制:(64mb)
题目描述
阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫。
今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔吉侬最喜欢的奶酪。
现在研究员们想知道,如果阿尔吉侬足够聪明,它最少需要多少时间就能吃到奶酪。
迷宫用一个 (R*C) 的字符矩阵来表示。
字符 (S) 表示阿尔吉侬所在的位置,字符 (E) 表示奶酪所在的位置,字符 (#) 表示墙壁,字符 (.) 表示可以通行。
阿尔吉侬在 (1) 个单位时间内可以从当前的位置走到它上下左右四个方向上的任意一个位置,但不能走出地图边界。
输入格式
第一行是一个正整数 (T) ,表示一共有 (T) 组数据。
每一组数据的第一行包含了两个用空格分开的正整数 (R) 和 (C) ,表示地图是一个 (R*C) 的矩阵。
接下来的 (R) 行描述了地图的具体内容,每一行包含了 (C) 个字符。字符含义如题目描述中所述。保证有且仅有一个 (S) 和 (E) 。
输出格式
对于每一组数据,输出阿尔吉侬吃到奶酪的最少单位时间。
若阿尔吉侬无法吃到奶酪,则输出“oop!”(只输出引号里面的内容,不输出引号)。
每组数据的输出结果占一行。
数据范围
(1 < T ≤ 10) ,
(2 ≤ R,C ≤ 200)
样例输入
3
3 4
.S..
###.
..E.
3 4
.S..
.E..
....
3 4
.S..
####
..E.
样例输出
5
1
oop!
解题思路:BFS
拿到给定的 (R*C) 的数组后,先遍历拿到 (S) 和 (E) 的坐标,用pair类对象来保存。
BFS思路: 将当前坐标的上下左右四个格子遍历一边,如果能走,就将能走的格子的坐标放入队列,循环内依次出列,再继续遍历出列的格子的上下左右,如此循环,知道没有格子可以走,即队列为空,就结束。
先将起始坐标入队,开一个 (dist) 数组用于保存距离,并将起始坐标的距离写为0。
进入循环,出队一个 pair t
,遍历此坐标的上下左右四个格子,如果能走,则将其坐标入队,并直接赋值距离 dist[x][y] = dist[t.x][t.y] + 1
,所有走过的格子将其标记为不能走。
循环直到走到了终点坐标即返回终点坐标距离 dist[e.x][e.y]
,如果队列为空的时候还未走到终点,循环结束,返回 oop!
。
类似题目: 2021寒假每日一题《红与黑》
解题代码-Java
import java.util.Queue;
import java.util.Scanner;
import java.util.LinkedList;
class pair {
int x, y;
public pair(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Main {
static int r, c;
static char[][] maze;
static int[][] dist;
static int[] dx = new int[]{0, 1, 0, -1};
static int[] dy = new int[]{-1, 0, 1, 0};
static String bfs(pair s, pair e) {
Queue<pair> q = new LinkedList<>();
q.offer(s);
dist[s.x][s.y] = 0;
while (!q.isEmpty()) {
pair t = q.poll();
for (int i = 0; i < 4; i++) {
int x = t.x + dx[i], y = t.y + dy[i];
if (x >= 0 && x < r && y >= 0 && y < c && maze[x][y] != '#') {
maze[x][y] = '#';
dist[x][y] = dist[t.x][t.y] + 1;
if (x == e.x && y == e.y) {
return "" + dist[x][y];
}
q.offer(new pair(x, y));
}
}
}
return "oop!";
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int t = input.nextInt();
while (t-- > 0) {
r = input.nextInt();
c = input.nextInt();
maze = new char[r][c];
dist = new int[r][c];
pair s = null, e = null;
for (int i = 0; i < r; i++) {
maze[i] = input.next().toCharArray();
for (int j = 0; j < c; j++) {
if (maze[i][j] == 'S') {
s = new pair(i, j);
}
if (maze[i][j] == 'E') {
e = new pair(i, j);
}
}
}
System.out.println(bfs(s, e));
}
input.close();
}
}