poj 2157 Maze(bfs)

题意:有一个迷宫,迷宫里面有5种门,A,B,C,D,E,对应的钥匙分别在迷宫为a,b,c,d,e这些点上,

打开这些门分别需要对应的所有钥匙,例如在迷宫里面有A门挡住了去路,那么你需要找到迷宫里所有的a才能打开A门;

‘x’表示墙,‘.’表示通道,‘S’表示出发点,‘G’表示终点,可以到达终点输出YES,否则输出NO;

思路:在出发之前先判断下迷宫中有多少种门,然后判断是否可以打开(找到对应的所有钥匙),如果可以打开,

将对应的门变为‘.'(通道),否则不改变(或者变为‘X’),然后再从S点走到G点;

寻找钥匙的过程可以用BFS搜索

代码如下:

#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <queue>
using namespace std;
//用结构体保存
struct Node{
    int x,y;
    int step;
};
Node start,end,A,B,C,D,E;
char map_[25][25];//保存迷宫
int m,n;
Node qa[425],qb[425],qc[425],qd[425],qe[425];//保存钥匙的位置
int ax[4]={-1,0,1,0};
int ay[4]={0,1,0,-1};
int vis[425][425];//标记数组
bool BFS(Node x){
    queue<Node> mq;
    while(!mq.empty()){
        mq.pop();
    }
    mq.push(start);
    vis[start.x][start.y]=1;
    while(!mq.empty()){
        Node no = mq.front();
        mq.pop();
        if(no.x==x.x&&no.y==x.y){
            return 1;
        }
        for(int i=0;i<4;i++){
            Node de = no;
            de.x = no.x+ax[i];
            de.y = no.y+ay[i];
            if(de.x>=0&&de.x<m&&de.y>=0&&de.y<n&&vis[de.x][de.y]==0&&map_[de.x][de.y]!='A'
               &&map_[de.x][de.y]!='B'&&map_[de.x][de.y]!='C'&&map_[de.x][de.y]!='D'&&map_[de.x][de.y]!='E'
               &&map_[de.x][de.y]!='X'){
                vis[de.x][de.y]=1;
                mq.push(de);
               }

        }
    }
    return 0;
}


int main()
{
    while(~scanf("%d%d",&m,&n)){
        if(m==0&&n==0)return 0;
        memset(map_,0,sizeof(map_));
        int ma=0,mb=0,mc=0,md=0,me=0;//用于记录对应点的数目
        for(int i=0;i<m;i++){//输入迷宫时,记录门的位置和钥匙的位置
            scanf("%s",map_[i]);
            for(int j=0;map_[i][j];j++){
                if(map_[i][j]=='S'){start.x = i;start.y=j;
                }else if(map_[i][j]=='G'){end.x = i;end.y=j;
                }else if(map_[i][j]=='A'){A.x=i;A.y=j;}
                else if(map_[i][j]=='B'){B.x=i;B.y=j;}
                else if(map_[i][j]=='C'){C.x=i;C.y=j;}
                else if(map_[i][j]=='D'){D.x=i;D.y=j;}
                else if(map_[i][j]=='E'){E.x=i;E.y=j;}
                if(map_[i][j]=='a'){
                    qa[ma].x=i;qa[ma++].y=j;
                }
                if(map_[i][j]=='b'){
                    qb[mb].x=i;qb[mb++].y=j;
                }
                if(map_[i][j]=='c'){
                    qc[mc].x=i;qb[mc++].y=j;
                }
                if(map_[i][j]=='d'){
                    qd[md].x=i;qd[md++].y=j;
                }
                if(map_[i][j]=='e'){
                    qe[me].x=i;qe[me++].y=j;
                }
            }
        }
        int sum=0;
        for(int i=0;i<ma;i++){
            memset(vis,0,sizeof(vis));//每次BFS后将标记数组还原,继续下次的BFS
            if(BFS(qa[i]))sum++;
            if(sum==ma){
                if(map_[A.x][A.y]=='A')
                    map_[A.x][A.y]='.';
            }

        }
        sum=0;
        for(int i=0;i<mb;i++){

            memset(vis,0,sizeof(vis));
            if(BFS(qb[i]))sum++;
            if(sum==mb){
                if(map_[B.x][B.y]=='B')
                    map_[B.x][B.y]='.';
            }
        }
        sum=0;
        for(int i=0;i<mc;i++){

            memset(vis,0,sizeof(vis));
            if(BFS(qc[i]))sum++;
            if(sum==mc){
                if(map_[C.x][C.y]=='C')
                    map_[C.x][C.y]='.';
            }
        }
        sum=0;
        for(int i=0;i<md;i++){

            memset(vis,0,sizeof(vis));
            if(BFS(qd[i]))sum++;
            if(sum==md){
                if(map_[D.x][D.y]=='D')
                    map_[D.x][D.y]='.';
            }
        }
        sum=0;
        for(int i=0;i<me;i++){

            memset(vis,0,sizeof(vis));
            if(BFS(qe[i]))sum++;
            if(sum==me){
                if(map_[E.x][E.y]=='E')
                    map_[E.x][E.y]='.';
            }
        }
        memset(vis,0,sizeof(vis));
        if(BFS(end)){
            printf("YES
");
        }else{
            printf("NO
");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hnzyyTl/p/4838542.html