思路:
求最短距离,肯定用宽搜BFS
这道题主要需要注意以下几个问题:
1.可能起点就是终点
2.可能起点就是传送门
3.可能起点就有障碍物
4.可能传送门的下一个点还是传送门
代码:
#include<bits/stdc++.h>
#define maxn 5050
using namespace std;
char grid[maxn][maxn]; //存储迷宫地图
int vis[maxn][maxn]; //记录每个位置是否被遍历过
struct node{ //用于宽搜的结构体
int x, y, step;
};
int main(){
int n, m, q;
int sx, sy, ex, ey; //(sx, sy)为起点, (ex, ey)终点
cin>>n>>m;
//输入地图
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
cin>>grid[i][j];
map<pair<int, int>, int> ma;//ma记录传送门起点, 如第一组数据2 2 2 4, ma[make_pair(2, 2)] = 1
map<int, pair<int, int> > mb;//mb记录传送门终点, 相对应mb[1] = make_pair(2, 4)
int a, b, c, d, k = 1; //k记录传送门的个数, ma和mb的记录
int dx[] = {-1, 0, 1, 0}, dy[] = {0, -1, 0 ,1};
memset(vis, 0, sizeof(vis));
cin>>q;
for(int i=0; i<q; i++){
cin>>a>>b>>c>>d;
ma[make_pair(a, b)] = k;
mb[k++] = make_pair(c, d);
}
cin>>ex>>ey;
sx = 1, sy = 1;
//如果起点就是终点,直接返回0
if(ex==1&&ey==1){
cout<<1<<endl;
return 0;
}
//如果起点就有障碍物,则输出No solution(我也不知道会不会卡这个,反正写了总没错)
if(grid[sx][sy]=='*'){
cout<<"No solution";
return 0;
}
//处理起点就是传送门的情况
while(ma[make_pair(sx, sy)]){
vis[sx][sy] = 1;
int tx = sx, ty = sy;
sx = mb[ma[make_pair(tx, ty)]].first;
sy = mb[ma[make_pair(tx, ty)]].second;
}
//宽搜队列
queue<node> que;
node nd;
nd.x = sx, nd.y = sy, nd.step = 0;
que.push(nd);
vis[sx][sy] = 1;
while(que.size()){
node t = que.front();
que.pop();
int x = t.x, y = t.y, step = t.step;
//到达终点,直接输出距离
if(x==ex && y==ey){
cout<<step;
return 0;
}
//如果过程中遇到障碍物,直接跳过
if(grid[x][y] == '*')
continue;
//向四个方向搜索
for(int i=0; i<4; i++){
int nx = x + dx[i], ny = y + dy[i];
if(nx>=1 && nx<=n && ny>=1 && ny<=m && grid[nx][ny]=='.' && !vis[nx][ny]){
vis[nx][ny] = 1;
//ma[{x, y}]大于0则表示该点为传送门
if(ma[make_pair(nx, ny)]){
//处理传送门下一个点还是传送门的情况
while(ma[make_pair(nx, ny)]){
int tx = nx, ty = ny;
nx = mb[ma[make_pair(tx, ty)]].first;
ny = mb[ma[make_pair(tx, ty)]].second;
}
//将不是传送门的点加入队列,注意这里不需要处理障碍点,前面已经处理了
node d;
d.x = nx, d.y = ny, d.step = step + 1;
que.push(d);
}
else{
//不是传送门直接加入队列,不用处理传送门理由同上
node d;
d.x = nx, d.y = ny, d.step = step + 1;
que.push(d);
}
}
}
}
//宽搜结束还没到达终点,直接输出No solution
cout<<"No solution";
return 0;
}