题目
题解
这道题是bfs对比于其他最简单的来说只是多了一个传送门的特判而已,又因为最多也就26个传送门;我们只要再开一个结构来存储传送门的起点和终点就可以了,
下面看代码实现,附带注释
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e3+9;
int n,m;
char a[N][N];//存图
bool b[N][N];//判重
int dx[4]={1,-1,0,0};//四个方向
int dy[4]={0,0,1,-1};
int ji[200];//传送门判断起点和终点
struct node
{
int x,y,cnt;
};
int stx,sty;//记录起点
struct chuang{//传送门
int cx,cy;
int rx,ry;
}ch[200];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin >> n >> m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin >> a[i][j];
if(a[i][j]=='@') stx=i,sty=j; //记录起点
if(a[i][j]>='A'&&a[i][j]<='Z'){ //传送门,如果ji[i][j]=0的话就代表第一次遇到这个字母
if(!ji[a[i][j]]) ch[a[i][j]].cx=i,ch[a[i][j]].cy=j,ji[a[i][j]]++;
else ch[a[i][j]].rx=i,ch[a[i][j]].ry=j;
}
}
queue<node>qu; // bfs
node x={stx,sty,0};
qu.push(x);
while(qu.size()){
x=qu.front();qu.pop();
if(b[x.x][x.y]) continue; // 重复就跳过
b[x.x][x.y]=1;
if(a[x.x][x.y]>='A'&&a[x.x][x.y]<='Z'){ //传送门就要直接传送
char cha=a[x.x][x.y];
if(ch[cha].cx==x.x&&ch[cha].cy==x.y)
{x.x=ch[cha].rx;x.y=ch[cha].ry;}
else {x.x=ch[cha].cx;x.y=ch[cha].cy; }
}
if(a[x.x][x.y]=='=') {cout << x.cnt ;return 0;} //找到终点,直接输出,结束
for(int i=0;i<4;i++){
node xin;
int xx,yy;
xx=x.x+dx[i],yy=x.y+dy[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!b[xx][yy]&&a[xx][yy]!='#')//判断是否合法
{
xin={xx,yy,x.cnt+1};
qu.push(xin);
}
}
}
}