本题做法
- BFS。
思路
本题其实难就难在传送门如何存储。我的做法是使用 3 个 map 存储传送门,一个 map 叫做 \(exist\)(map<char,bool>
),代表传送门 \(c\) 是否存在(就是有没有输入过了),是为了后面的存储判断做准备;第二个 map 叫做 \(lastdoor\)(map<char,pair<int,int>>
),代表传送门 \(c\) 的第一次出现点在哪个位置;最后一个 map 叫做 \(door\)(map<pair<int,int>,pair<int,int>>
),存储的是传送门位置 \((x,y)\) 的另一个对应传送门位置。
读入时,若当前读入的是字符(c>='A'&&c<='Z'
),则判断是否 \(exist[c]\),若真,则做如下操作:
//互相将对应的传送门位置赋值
door[lastdoor[mp[i][j]]]={i,j};
door[{i,j}]=lastdoor[mp[i][j]];
若假,则做如下操作:
//记录已经存在传送门,并记录第一个传送门的位置
exist[mp[i][j]]=1;
lastdoor[mp[i][j]]={i,j};
随后就是愉快的 BFS 模板题了,需要注意的是,我们不能将传送门位置的 \(vis\)(即是否来到过)数组设为 true
,因为我们可能需要多次走一个传送门。
代码
#include <bits/stdc++.h>
#define endl '\n'
#define ll long longusing namespace std;const int INF = 0x3f3f3f3f;
const double EPS = 1e-8;
const int N = 305;
const int fx[5] = { 0, 0, 1, 0, -1 };
const int fy[5] = { 0, 1, 0, -1, 0 };#define CHECK(X, Y) \(X >= 1 && X <= n && Y >= 1 && Y <= m && mp[X][Y] != '#' && !vis[X][Y])struct coord {int x;int y;int s;
};int n, m, sx, sy, ex, ey;
char mp[N][N];
bool vis[N][N];
map<pair<int, int>, pair<int, int>> door; // 存储每一个点位对应的另一个传送门
map<char, bool> exist; // 用于在输入时判断这个传送门以前是否有输入过了
map<char, pair<int, int>>lastdoor; // 用于在输入时存储每个传送门的第一次出现点位int main() {cin >> n >> m;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {cin >> mp[i][j];if (mp[i][j] == '@') {sx = i;sy = j;mp[i][j] = '.';} else if (mp[i][j] == '=') {ex = i;ey = j;mp[i][j] = '.';} else if (mp[i][j] >= 'A' && mp[i][j] <= 'Z') {if (exist[mp[i][j]]) {door[lastdoor[mp[i][j]]] = { i, j };door[{ i, j }] = lastdoor[mp[i][j]];} else {exist[mp[i][j]] = 1;lastdoor[mp[i][j]] = { i, j };}}}}coord c = { sx, sy, 0 };vis[sx][sy] = 1;queue<coord> q;q.push(c);while (!q.empty()) {c = q.front();q.pop();int x = c.x, y = c.y, s = c.s;// cout << "(" << x << "," << y << ")" << endl;if (x == ex && y == ey) {cout << s << endl;return 0;}if (door.find({ x, y }) != door.end()) {pair<int, int> p = door[{ x, y }];x = p.first;y = p.second;}int tx, ty;for (int i = 1; i <= 4; i++) {tx = x + fx[i];ty = y + fy[i];if (CHECK(tx, ty)) {vis[tx][ty] = 1;q.push({ tx, ty, s + 1 });}}}return 0;
}