【UESTC - 149】 解救小Q 【BFS】

小Q被邪恶的大魔王困在了迷宫里,love8909决定去解救她。
迷宫里面有一些陷阱,一旦走到陷阱里,就会被困身亡:(,迷宫
里还有一些古老的传送阵,一旦走到传送阵上,会强制被传送到
传送阵的另一头。

现在请你帮助love8909算一算,他至少需要走多少步才能解
救到小Q?

Input
第一行为一个整数TT,表示测试数据组数。

每组测试数据第一行为两个整数NN,MM,(1≤N,M≤501≤N,M≤50)表示
迷宫的长和宽。

接下来有NN行,每行MM个字符,是迷宫的具体描述。

.表示安全的位置

表示陷阱,

Q表示小Q的位置
L表示love8909所在位置,
数据保证love8909只有一个,数据也保证小Q只有一个。

小写字母a-z表示分别表示不同的传送阵,数据保证传送阵
两两配对。

Output
每组数据输出一行,解救小Q所需的最少步数,如果无论如何都
无法救小Q,输出-1。

Sample Input
2

5 5
….L
.###.
b#b#a

.

…Qa

5 5
….L
.###.
.#.#.

.

…Q.
Sample Output
3
-1

这两天又写到一个相似的,还是有点写不好,把那道题补完之后,才想起来这道题还没有补,就赶紧补了下,没想到一次就a了【主要还是细心吧】。

代码

#include<bits/stdc++.h>
#define MAXN 100 
#define MAXM 2000000+10 
#define INF 100000000
using namespace std;
struct Door{
    int x,y;
}d[MAXN];
struct Node {
    int x,y,step;
};
int dcnt;
int n,m;
Node S,T;
int pos[MAXN][MAXN];
char mp[MAXN][MAXN];
bool vis[MAXN][MAXN];
int to[][2]={1,0,-1,0,0,-1,0,1};
void getmap(){
    dcnt=-1;
    for(int i=0;i<n;i++){
        scanf("%s",mp[i]);
        for(int j=0;j<m;j++){
            if(mp[i][j]=='Q') T={i,j,0};
            if(mp[i][j]=='L') S={i,j,0};
            if(mp[i][j]>='a'&&mp[i][j]<='z') {
                 d[++dcnt]={i,j};
                 pos[i][j]=mp[i][j];
            }
        }
    } 
} 
void bfs(Node st,Node ed){
    queue<Node>Q;
    memset(vis,0,sizeof(vis));
    mp[ed.x][ed.y]='.';
    vis[st.x][st.y]=1; Q.push(st);
    Node now,nexts;
    while(!Q.empty()){
        now=Q.front();Q.pop();
        if(now.x==ed.x&&now.y==ed.y) {  printf("%d\n",now.step); return ;}
        for(int i=0;i<4;i++){
            int nx=now.x+to[i][1]; int ny=now.y+to[i][0];
            if(vis[nx][ny]||mp[nx][ny]=='#') continue;
            if(nx<0||ny<0||nx>=n||ny>=m) continue;
            if(mp[nx][ny]>='a'&&mp[nx][ny]<='z'){
                int kins=pos[nx][ny];
                vis[nx][ny]=1;
                 for(int j=0;j<=dcnt;j++) {
                    if(nx==d[j].x&&ny==d[j].y) continue;
                    if(pos[d[j].x][d[j].y]==kins) {
                        nexts={d[j].x,d[j].y,now.step+1};
                        Q.push(nexts);  break;
                     } 
                 }
                 continue;
            } 
            nexts={nx,ny,now.step+1};
            vis[nx][ny]=1;
            Q.push(nexts);
        }
    }
    puts("-1");
}
int main(){
    int t;cin>>t;
    while(t--){
        scanf("%d%d",&n,&m);
        getmap();
        bfs(S,T);
    }    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值