题目大意:
.
表示安全的位置#
表示陷阱,Q
表示小Q的位置L
表示love8909所在位置,
a
-z
表示分别表示不同的传送阵,数据保证传送阵两两配对。
思路分析:注意传送带就是把两个点黏在一起,并把当前的传送带的位置标记为1。
测试输入:5 5
....L
.###a
a#...
##.##
...Q.
输出:9
代码实现:
#include<cstdio>
#include<cstring>
#include<queue>
#include<cctype>
using namespace std;
int n,m,Qx,Qy,Lx,Ly,dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
bool visit[55][55];
char mp[55][55];
struct Transport{
int x1,y1,x2,y2;
bool mark;
}trans[30];
struct Status{
int x,y,step;
Status(int _x=0,int _y=0,int _step=0):x(_x),y(_y),step(_step){}
};
int bfs(){
queue<Status> q;
memset(visit,0,sizeof(visit));
q.push(Status(Lx,Ly,0));
visit[Lx][Ly]=1;
Status head,now;
int i,to;
while(!q.empty()){
head=q.front();
if(mp[head.x][head.y]=='Q') return head.step;
q.pop();
for(i=0;i<4;++i){
now.x=head.x+dx[i];
now.y=head.y+dy[i];
if(0>now.x||now.x>=n||0>now.y||now.y>=m||visit[now.x][now.y]||mp[now.x][now.y]=='#') continue;
now.step=head.step+1;
visit[now.x][now.y]=1;
if(islower(mp[now.x][now.y])){
to=mp[now.x][now.y]-'a';
visit[now.x][now.y]=1;
if(now.x==trans[to].x1&&now.y==trans[to].y1) now.x=trans[to].x2,now.y=trans[to].y2;
else now.x=trans[to].x1,now.y=trans[to].y1;
}
q.push(now);
}
}
return -1;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(trans,0,sizeof(trans));
int x,i,j;
for(i=0;i<n;++i){
scanf("%s",mp[i]);
for(j=0;j<m;++j){
if(mp[i][j]=='L') Lx=i,Ly=j;
else if(islower(mp[i][j])){
x=mp[i][j]-'a';
if(trans[x].mark==0) trans[x].x1=i,trans[x].y1=j,trans[x].mark=1;
else trans[x].x2=i,trans[x].y2=j;
}
}
}
printf("%d\n",bfs());
}
}