思想
我们把所有的传送点都放到vector里,然后就正常从起点开始向终点搜索。如果在过程中遇到传送点,那么就把传送点也放入到队列中。
code
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int>PII;
int n, m, x1, ya;
const int N = 210;
char g[N][N];
int vis[N][N];
vector<PII> v;
struct NODE {
int x, y, cnt;
};
int dx[] = {0,1,0,-1}, dy[] = {-1,0,1,0};
int bfs(int x, int y) {
queue<NODE> q;
q.push({x, y, 0});
while (!q.empty()) {
NODE t = q.front();
q.pop();
if (g[t.x][t.y]=='P')
return t.cnt;
for (int i = 0; i < 4; i++) {
int tx = dx[i] + t.x, ty = dy[i] + t.y;
if (tx < 1 || tx > n || ty < 1 || ty > m || g[tx][ty] == '#' || vis[tx][ty] == 1)
continue;
vis[tx][ty] = 1;
if (g[tx][ty] == '@') {
for (auto it : v) {
//因为所有的传送点都放到vector里了,所以当前正在遍历的点也放到vector了。遇到当前点就跳过
if (tx == it.first && ty == it.second || vis[it.first][it.second] == 1)
continue;
q.push({it.first, it.second, t.cnt + 1});
vis[it.first][it.second] = 1;
}
} else
q.push({tx, ty, t.cnt + 1});
}
}
return -1;
}
signed main() {
cin.tie(nullptr)->sync_with_stdio(false);
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] == 'S')
x1 = i, ya = j;
if (g[i][j] == '@')
v.push_back({i, j});
}
}
cout << bfs(x1, ya);
return 0;
}