A.解救小Q
BFS。每次到达一个状态时看是否是在传送阵的一点上,是则传送到另一点即可。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> using namespace std; #define NA 100007 char mp[52][52]; struct status { int x,y; int l; }; int vis[52][52]; struct transport { int x1,y1; //初始点 int x2,y2; //传送目标点 int flag; }a[27]; int n,m; int head,tail; int pathx[4]={0,1,0,-1}; int pathy[4]={-1,0,1,0}; bool OK(int nx,int ny) { return nx>=0&&ny>=0&&nx<n&&ny<m; } int bfs(int x,int y) { status now,next; queue<status> que; now.x=x; now.y=y; now.l=0; vis[now.x][now.y]=1; que.push(now); while(!que.empty()) //队列非空 { now = que.front(); que.pop(); for(int i=0;i<4;i++) { int nx=now.x+pathx[i]; int ny=now.y+pathy[i]; if(vis[nx][ny] || !OK(nx,ny)) continue; if(mp[nx][ny]=='Q') return now.l+1; if(mp[nx][ny]!='#') { if(mp[nx][ny]>='a'&&mp[nx][ny]<='z') { int h=mp[nx][ny]-'a'; if(a[h].x1!=nx||a[h].y1!=ny) //初始点和目标点可以互换 { next.x=a[h].x1; next.y=a[h].y1; } else { next.x=a[h].x2; next.y=a[h].y2; } next.l=now.l+1; que.push(next); } else { next.x=nx; next.y=ny; next.l=now.l+1; que.push(next); } vis[nx][ny]=1; } } } return -1; } int main() { int T,x,y; int N,M; scanf("%d",&T); while(T--) { memset(vis,0,sizeof(vis)); memset(mp,0,sizeof(mp)); for(int j=0;j<27;j++) a[j].flag=0; scanf("%d%d",&N,&M); n=N; m=M; getchar(); for(int i=0;i<N;i++) { for(int j=0;j<M;j++) { scanf("%c",&mp[i][j]); if(mp[i][j]=='L') { x=i; y=j; } if(mp[i][j]>='a'&&mp[i][j]<='z') { int h=mp[i][j]-'a'; if(a[h].flag==0) { a[h].x1=i; a[h].y1=j; a[h].flag=1; } else if(a[h].flag==1) { a[h].x2=i; a[h].y2=j; } } } getchar(); } printf("%d\n",bfs(x,y)); } return 0; }