题意:一个迷宫里面有障碍和传送门,遇到传送门就会被强制传送到另一个地方,问到达Q点的最短距离
思路:bfs
错误:最开始的时候以为传送门两端是等价的,就直接把两边一起入队列,距离赋一样的值,后来发现原来是强制转移,这样两边就不等价了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct pos
{
int x;
int y;
pos(int x=-1,int y=-1):x(x),y(y){}
};
bool operator == (const pos &a,const pos &b)
{
return a.x==b.x&&a.y==b.y;
}
const int dir[4][2]={-1,0,0,1,1,0,0,-1};
int n,m;
bool judge(pos a)
{
if(a.x<0||a.x>=n)return 0;
if(a.y<0||a.y>=m)return 0;
return 1;
}
char maze[55][55];
pos gate[30][2];
pos start;
pos fin;
int dis[55][55];
void bfs()
{
queue<pos> q;
while(!q.empty())q.pop();
dis[start.x][start.y]=0;
q.push(start);
while(!q.empty())
{
pos now=q.front();
q.pop();
for(int d=0;d<4;++d)
{
pos to;
to.x=now.x+dir[d][0];
to.y=now.y+dir[d][1];
if(!judge(to))continue;
if(maze[to.x][to.y] == '#')continue;
int far=dis[now.x][now.y]+1;
if(maze[to.x][to.y]>='a'&&maze[to.x][to.y]<='z'){
int ch = maze[to.x][to.y]-'a';
if(to==gate[ch][1])
{
to=gate[ch][0];
}else{
to=gate[ch][1];
}
}
if(dis[to.x][to.y]>far||dis[to.x][to.y]== -1){
dis[to.x][to.y] = far;
q.push(to);
}
}
}
}
int main()
{
// freopen("data.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
memset(dis,-1,sizeof(dis));
for(int i=0;i<30;++i)
{
gate[i][0]=gate[i][1]=pos(-1,-1);
}
for(int i=0;i<n;++i)
{
scanf("%s",maze[i]);
while(strlen(maze[i])!=m)scanf("%s",maze[i]);
for(int j=0;j<m;++j)
{
if(maze[i][j]=='Q'){
fin.x=i;
fin.y=j;
}else if(maze[i][j]=='L'){
start.x=i;
start.y=j;
}else if(maze[i][j]>='a'&&maze[i][j]<='z'){
int tmp=maze[i][j]-'a';
if(gate[tmp][0].x==-1){
gate[tmp][0]=pos(i,j);
}else {
gate[tmp][1]=pos(i,j);
}
}
}
}
bfs();
printf("%d\n",dis[fin.x][fin.y]);
}
return 0;
}