迷宫寻宝(一)(BFS)

http://acm.nyist.net/JudgeOnline/problem.php?pid=82

 

迷宫寻宝(一)

时间限制:1000 ms  |  内存限制:65535 KB

难度:4

描述

一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫里有N个编过号的门(N<=5),它们分别被编号为A,B,C,D,E.为了找到宝藏,ACM必须打开门,但是,开门之前必须在迷宫里找到这个打开这个门所需的所有钥匙(每个门都至少有一把钥匙),例如:现在A门有三把钥匙,ACM就必须找全三把钥匙才能打开A门。现在请你编写一个程序来告诉ACM,他能不能顺利的得到宝藏。

 

输入

输入可能会有多组测试数据(不超过10组)。
每组测试数据的第一行包含了两个整数M,N(1<N,M<20),分别代表了迷宫的行和列。接下来的M每行有N个字符,描述了迷宫的布局。其中每个字符的含义如下:
.表示可以走的路
S:表示ACM的出发点
G表示宝藏的位置
X表示这里有墙,ACM无法进入或者穿过。
A,B,C,D,E表示这里是门,a,b,c,d,e表示对应大写字母的门上的钥匙。
注意ACM只能在迷宫里向上下左右四个方向移动。

最后,输入0 0表示输入结束。

输出

每行输出一个YES表示ACM能找到宝藏,输出NO表示ACM找不到宝藏。

样例输入

4 4

S.X.

a.X.

..XG

....

3 4

S.Xa

.aXB

b.AG

0 0

样例输出

YES

NO

 

 

 

 

001.#include <cstdio>

002.#include <cmath>

003.#include <algorithm>

004.#include <cstring>

005.#include <iostream>

006.#include <queue>

007.using namespace std;

008. 

009.int n,m;

010.char map[25][25];

011.int book[25][25];

012.int need[5];

013.int stx,sty;

014. 

015.struct node

016.{

017.int x;

018.int y;

019.}st,ed;

020. 

021.int bfs()

022.{

023.memset(book,0,sizeof(book));

024.int next[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

025.int flag=0;

026.st.x=stx;st.y=sty;

027.book[st.x][st.y]=1;

028.queue<node>Q;

029.Q.push(st);

030.while(!Q.empty())

031.{

032.st=Q.front();

033.Q.pop();

034.for(int i=0;i<4;i++)

035.{

036.ed.x=st.x+next[i][0];

037.ed.y=st.y+next[i][1];

038.if(map[ed.x][ed.y]=='G')

039.{

040.return 1;

041.}

042.if(book[ed.x][ed.y]==0&&ed.x>=0&&ed.y>=0&&ed.x<n&&ed.y<=m&&map[ed.x][ed.y]!='X')

043.{

044.if(map[ed.x][ed.y]>='a'&&map[ed.x][ed.y]<='e')

045.{

046.need[map[ed.x][ed.y]-'a']--;

047.flag=1;

048.map[ed.x][ed.y]='.';

049.}

050.if(map[ed.x][ed.y]>='A'&&map[ed.x][ed.y]<='E')

051.{

052.if(need[map[ed.x][ed.y]-'A']!=0)

053.{

054.continue ;

055.}

056.}

057.book[ed.x][ed.y]=1;

058.Q.push(ed);

059.}

060.}

061.}

062.if(flag==0)

063.{

064.return -1;

065.}

066.else

067.{

068.return 0;

069.}

070.}

071. 

072.int main()

073.{

074.while(~scanf("%d %d",&n,&m))

075.{

076.memset(need,0,sizeof(need));

077.memset(book,0,sizeof(book));

078.if(n==0&&m==0)

079.{

080.break;

081.}

082.for(int i=0;i<n;i++)

083.{

084.scanf("%s",map[i]);

085.}

086.for(int i=0;i<n;i++)

087.{

088.for(int j=0;j<m;j++)

089.{

090.if(map[i][j]=='S')

091.{

092.stx=i;sty=j;

093.}

094.if(map[i][j]>='a'&&map[i][j]<='e')

095.{

096.need[map[i][j]-'a']++;

097.}

098.}

099.}

100.while(1)

101.{

102.int t=bfs();

103.if(t==1)

104.{

105.printf("YES\n");

106.break ;

107.}

108.if(t==0)

109.{

110.continue ;

111.}

112.if(t==-1)

113.{

114.printf("NO\n");

115.break;

116.}

117.}

118.}

119.return 0;

120.}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值