这道题只需往bfs模板上加个特殊判断就行了。思路这不详解,看代码注释。
Code
#include<bits/stdc++.h>
using namespace std;
int n,m,zx,zy;
char a[305][305];
int v[301][301];
int ans=-1;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
struct point{
int x1,y1,step;
}start;
queue<point> dl;
point find(int tx,int ty,int time){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]==a[tx][ty]&&(i!=tx||j!=ty)){//寻找另一个传送门
tx=i;
ty=j;
return (point){i,j,time};记录坐标与步数。
}
}
}
}
int main(){
cin>>n>>m;
string s;
for(int i=1;i<=n;i++){
cin>>s;//输入地图
for(int j=1;j<=m;j++){
a[i][j]=s[j-1];
if(a[i][j]=='@'){//寻找起点
start.x1=i;//记录起点坐标
start.y1=j;
}
if(a[i][j]=='='){//寻找终点
zx=i,zy=j;//记录终点坐标
}
}
}
start.step=0;//将起点步数初始化
v[start.x1][start.y1]=1;//标记起点
dl.push(start);//将起点加入队列
while(!dl.empty()){
point head=dl.front();//拿出队列第一项
dl.pop();//将第一项推出队列
if(head.x1==zx&&head.y1==zy){//是否到达终点
ans=max(ans,head.step); //寻找最佳答案
cout<<ans<<endl;//输出答案
return 0;
}
for(int i=0;i<4;i++){//枚举四方向
int tx=head.x1+dx[i];//记录四方向坐标
int ty=head.y1+dy[i];
if(a[tx][ty]>='A'&&a[tx][ty]<='Z'){//看是否到达传送门
auto nd = find(tx,ty,head.step+1);//寻找传送门所到达地
if(!v[nd.x1][nd.y1])dl.push(nd);//到达地坐标推入队列
v[nd.x1][nd.y1]=1;//标记
continue;
}
if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]!='#'&&!v[tx][ty]){//是否能走&是否越界
v[tx][ty] = 1;//标记
point temp;
temp.x1 = tx;
temp.y1 = ty;
temp.step = head.step + 1;
dl.push(temp);//将变化位置推入队列
}
}
}
return 0;
}