题目描述
少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶。叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。迷阵由M×N个方格组成,有的方格内有可以瞬秒李逍遥的怪物,而有的方格内则是安全。现在李逍遥想尽快找到仙药,显然他应避开有怪物的方格,并经过最少的方格,而且那里会有神秘人物等待着他。现在要求你来帮助他实现这个目标。
下图 显示了一个迷阵的样例及李逍遥找到仙药的路线。

输入
输入有多组测试数据. 每组测试数据以两个非零整数 M 和 N 开始,两者均不大于20。M 表示迷阵行数, N 表示迷阵列数。接下来有 M 行, 每行包含N个字符,不同字符分别代表不同含义:
1)‘@’:少年李逍遥所在的位置;
2)‘.’:可以安全通行的方格;
3)‘#’:有怪物的方格;
4)‘*’:仙药所在位置。
当在一行中读入的是两个零时,表示输入结束。
输出
对于每组测试数据,分别输出一行,该行包含李逍遥找到仙药需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药, 则输出 -1。
样例输入
复制
8 8
.@##...#
#....#.#
#.#.##..
..#.###.
#.#...#.
..###.#.
...#.*..
.#...###
6 5
.*.#.
.#...
..##.
.....
.#...
....@
9 6
.#..#.
.#.*.#
.####.
..#...
..#...
..#...
..#...
#.@.##
.#..#.
0 0
样例输出
复制
10
8
-1
代码如下
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_set>
#include <sstream>
using namespace std;
int bfs(vector<vector<char>>& grid, pair<int, int> start) {
int rows = grid.size();
int cols = grid[0].size();
vector<pair<int, int>> directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
queue<pair<int, int>> q;
unordered_set<string> visited;
q.push(start);
visited.insert(to_string(start.first) + "," + to_string(start.second));
int steps = 0;
while (!q.empty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
auto [x, y] = q.front();
q.pop();
if (grid[x][y] == '*') {
return steps;
}
for (const auto& dir : directions) {
int nx = x + dir.first;
int ny = y + dir.second;
if (nx >= 0 && nx < rows && ny >= 0 && ny < cols &&
visited.find(to_string(nx) + "," + to_string(ny)) == visited.end() &&
grid[nx][ny] != '#') {
visited.insert(to_string(nx) + "," + to_string(ny));
q.push({nx, ny});
}
}
}
steps++;
}
return -1;
}
int findShortestPath(vector<vector<char>>& grid) {
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[i].size(); j++) {
if (grid[i][j] == '@') {
return bfs(grid, {i, j});
}
}
}
return -1;
}
int main() {
string input = R"(
8 8
.@##...#
#....#.#
#.#.##..
..#.###.
#.#...#.
..###.#.
...#.*..
.#...###
6 5
.*.#.
.#...
..##.
.....
.#...
....@
9 6
.#..#.
.#.*.#
.####.
..#...
..#...
..#...
..#...
#.@.##
.#..#.
0 0)";
istringstream reader(input);
string line;
while (getline(reader, line)) {
istringstream iss(line);
int M, N;
if (!(iss >> M >> N)) break;
if (M == 0 && N == 0) break;
vector<vector<char>> grid(M, vector<char>(N));
for (int i = 0; i < M; i++) {
getline(reader, line);
for (int j = 0; j < N; j++) {
grid[i][j] = line[j];
}
}
int result = findShortestPath(grid);
cout << result << endl;
}
return 0;
}
2041

被折叠的 条评论
为什么被折叠?



