题目大意
一个迷宫中,四面都是墙(W),起点(S)、终点(E)、钥匙(K)、门(D)各只出现一次,寻找最短路径
难点
在寻找最短路径的同时如果会遇到钥匙再走会经过门的最短路,否则continue(直接不走门),等到遇到钥匙再走门
学会的技巧
不仅可以用dist来标记是否走过某个点和记录路径长度,还可以写结构体来记录,并且利用三维vis数组就可以很方便记录行到当前点时是否有钥匙
#include<bits/stdc++.h>
using namespace std;
int h,w;
int sx,sy,ex,ey;
char g[510][510];
bool vis[510][510][2];//利用三维数组不仅能判断某点是否走过 还能判断是否携带钥匙
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
struct Node{
int x,y;
int step; //记录路径长度 无需另外的变量记录
int key; //记录是否有钥匙
};
int bfs(){
queue<Node>q;
q.push({sx,sy,0,0});
vis[sx][sy][0]=1;
while(!q.empty()){
Node cur=q.front();
q.pop();
if(cur.x==ex&&cur.y==ey) return cur.step;
for(int i=0;i<4;++i){
int nx=cur.x+dx[i];
int ny=cur.y+dy[i];
int KeyPoint=cur.key;
int step=cur.step;
if(nx<0||nx>=h||ny<0||ny>=w||g[nx][ny]=='W') continue;
if(g[nx][ny]=='K') KeyPoint=1;
if(g[nx][ny]=='D'&&KeyPoint==0) continue;
if(!vis[nx][ny][KeyPoint]){
q.push({nx,ny,step+1,KeyPoint});
vis[nx][ny][KeyPoint]=1;
}
}
}
return -1;
}
int main(){
cin>>h>>w;
for(int i=0;i<h;++i){
for(int j=0;j<w;++j){
cin>>g[i][j];
if(g[i][j]=='S'){
sx=i;
sy=j;
}
else if(g[i][j]=='E'){
ex=i;
ey=j;
}
}
}
cout<<bfs()<<endl;
return 0;
}

京公网安备 11010502036488号