用pair开二维数组,存放两个传送门的坐标
注意:要标记当前走到的传送门,不是标记传送后的传送门
eg:走到(3,3),传送到(4,5),要标记33,不是45,因为需要用后来的传送门再传送回去
# # # # # = #
. . . . . . #
# # A # # # #
@ . . # A . .
# # # # # # #
#include <algorithm>
#include <cstring>
#include <iostream>
#include<queue>
using namespace std;
const int N = 305;
typedef pair<int, int> PII;
PII portal[26][2];//传送门下标
char g[N][N];
int vis[N][N], dis[N][N];
int n, m;
int sx, sy, ex, ey;
int d[2][4] = {0,-1,0,1,1,0,-1,0};//方向数组
PII get(int x, int y) {//返回另一个传送门
int c = g[x][y] - 'A';
if (portal[c][0] != make_pair(x,y))
return portal[c][0];
return portal[c][1];
}
void bfs(int xx, int yy) {
queue<PII> q;
vis[xx][yy] = 1;
q.push({xx, yy});
while (!q.empty()) {
PII cur = q.front();
q.pop();
int x = cur.first, y = cur.second;
if (x == ex && y == ey) {
return;
}
for (int i = 0; i < 4; i++) {
int fx = x + d[0][i], fy = y + d[1][i];
if (fx < 1 || fx > n || fy < 1 || fy > m || vis[fx][fy] ||//不合法的点
g[fx][fy] == '#')
continue;
else if (g[fx][fy] >= 'A' && g[fx][fy] <='Z') {//传送门
vis[fx][fy] = 1;
PII fxy = get(fx, fy);
dis[fxy.first][fxy.second] = dis[x][y] + 1;
q.push(fxy);
} else {// '.'
vis[fx][fy] = 1;
dis[fx][fy] = dis[x][y] + 1;
q.push({fx, fy});
}
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> g[i][j];
if (g[i][j] == '@') {
sx = i, sy = j;
}
else if (g[i][j] == '=')
ex = i, ey = j;
else if (g[i][j] >= 'A' && g[i][j] <= 'Z') {//判断是第几次出现的传送门
int c = g[i][j] - 'A';
if (portal[c][0].first == 0)
portal[c][0] = {i, j};
else
portal[c][1] = {i, j};
}
}
}
bfs(sx, sy);
cout << dis[ex][ey];
return 0;
}