【BFS】迷宫寻宝(一)(nyoj-82)

来源:互联网 发布:广东网络干部培训学院 编辑:程序博客网 时间:2024/06/06 03:07

题目链接点击打开链接

BFS题,看下NYOJ的讨论区,感觉数据挺变态。不过居然一遍就AC了......
好吧,个人觉得这题比较恼人的地方就是,一扇门需要集齐地图中的所有钥匙才能够打开。

这一点我刚写的时候没有仔细看(还以为是一把钥匙一扇门),结果对题目给的第二组测试数据纠结了很久.....

我的思路是:开一个key数组,在录入地图的时候,每逢a-e的钥匙出现,就计数+1;

在BFS过程中,每次遇到了一把钥匙,相应的计数就减去1,这样,当一把钥匙计数为0时,就代表着所有的钥匙都已经收集完全,可以打开对应的们了。

然而,有的钥匙由于被某一扇门阻隔,当前状态下无法收集,我们需要将别的门打开之后才能收集到。因此,判断当前状态下无法开启的们,未必在整个过程中都无法开启。因此,我们不能简单的在否定“入队”操作之后置之不理。

我的方法是将不能打开的们重新插入队尾。当然,为了防止死循环,必须先判断队列是否为空,如果队列为空,则表示该们无论如何都无法开启。

具体实现如下:

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;char map[35][35];bool visit[35][35];int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};int key[5]={0};int n,m;struct node{       int i,j;};bool in_limit(node & in){       if(in.i<1||in.j<1||in.i>n||in.j>m||visit[in.i][in.j])              return false;       char temp=map[in.i][in.j];       if(temp=='X')              return false;       if(temp<='e'&&temp>='a')              key[temp-'a']--;       return true;}bool BFS(int si,int sj){       node in,out;       in.i=si;       in.j=sj;       queue<node>que;       que.push(in);       visit[in.i][in.j]=1;       while(!que.empty())       {              out=que.front();              que.pop();              int tep=map[out.i][out.j];              if(tep=='G')                     return true;              if(tep<='E'&&tep>='A')              {                     if(key[tep-'A']==0)                     {                            map[out.i][out.j]='.';                     }                     else                     {                            if(que.empty())                                   return false;                            else                            {                                   que.push(out);                                   continue;                            }                     }              }              for(int i=0;i<4;i++)              {                     in.i=out.i+dir[i][0];                     in.j=out.j+dir[i][1];                     if(!in_limit(in))                            continue;                     visit[in.i][in.j]=1;                     que.push(in);              }       }       return false;}int main(){       while(scanf("%d%d",&n,&m)!=EOF&&(m||n))       {              getchar();              memset(key,0,sizeof(key));              int si,sj;              memset(visit,0,sizeof(visit));              for(int i=1;i<=n;i++)                     for(int j=1;j<=m;j++)                     {                            cin>>map[i][j];                            if(map[i][j]=='S')                            {                                   si=i;                                   sj=j;                            }                            if(map[i][j]<='e'&&map[i][j]>='a')                                   key[map[i][j]-'a']++;                     }              if(BFS(si,sj))                     printf("YES\n");              else                     printf("NO\n");       }       return 0;}


原创粉丝点击