现有一个n∗m大小的迷宫,其中1
表示不可通过的墙壁,0
表示平地,2
表示传送点。每次移动只能向上下左右移动一格,且只能移动到平地或传送点上。当位于传送点时,可以选择传送到另一个2
处(传送不计入步数),也可以选择不传送。求从迷宫左上角到右下角的最小步数。
解题思路:
带有传送点,我们只需要将传送目的点也加入队列即可。
完整代码如下:
#include <iostream>
#include <queue>
#include <map>
using namespace std;
int maze[101][101];
int inq[101][101] = {false};
int dx[4] = {-1,1,0,0};
int dy[4] = {0,0,-1,1};
int n,m;
struct node{
int x;
int y;
int step = 0;
};
vector<node> trans;
bool isvalid(int x,int y){
if(maze[x][y]!=1&&x>=0&&x<n&&y>=0&&y<m&&!inq[x][y]){
return true;
}
return false;
}
int BFS(int heng,int lie,int step){
queue<node> q;
node first;
first.x = heng;
first.y = lie;
first.step = step;
q.push(first);
inq[heng][lie] = true;
while(!q.empty()){
node front = q.front();
q.pop();
if(front.x==n-1&&front.y==m-1){
return front.step;
}
for(int i=0;i<4;i++){
int newx = front.x+dx[i];
int newy = front.y+dy[i];
int newstep = front.step+1;
if(isvalid(newx,newy)){
node newtemp;
newtemp.x = newx;
newtemp.y = newy;
newtemp.step = newstep;
q.push(newtemp);
inq[newx][newy] = true;
if (maze[newx][newy] == 2) {
for(int i=0;i<2;i++){
if(newx==trans[i].x&&newy==trans[i].y){
int chuanx = trans[(i+1)%2].x;
int chuany = trans[(i+1)%2].y;
inq[chuanx][chuany] = true;
node chuan;
chuan.x = chuanx;
chuan.y = chuany;
chuan.step = newstep;
q.push(chuan);
break;
}
}
}
}
}
}
return -1;
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>maze[i][j];
if(maze[i][j]==2){
node temp;
temp.x = i;
temp.y = j;
trans.push_back(temp);
}
}
}
cout<<BFS(0,0,0)<<endl;
return 0;
}