迷宫寻宝(一)
时间限制:
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
-
输入可能会有多组测试数据(不超过10组)。
-
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #include<queue> int n,m; int vis[21][21]; char a[21][21]; int dx[4]={0,0,1,-1}; int dy[4]={1,-1,0,0}; int key[5]={0}; struct zz { int x; int y; }f1,f2; int inlimit(zz f1) { if(f1.x<1||f1.y<1||f1.x>n||f1.y>m||vis[f1.x][f1.y]) return 0; char temp=a[f1.x][f1.y]; if(temp=='X') return 0; if(temp>='a'&&temp<='e') key[temp-'a']--; return 1; } int bfs(int x,int y) { queue<zz>q; f1.x=x;f1.y=y; q.push(f1); vis[f1.x][f1.y]=1; while(!q.empty()) { f1=q.front(); q.pop(); int tmp=a[f1.x][f1.y]; if(tmp=='G') return 1; if(tmp<='E'&&tmp>='A') { if(key[tmp-'A']==0) a[f1.x][f1.y]='.'; else { if(q.empty()) return 0; else { q.push(f1); continue; } } } for(int i=0;i<4;i++) { f2.x=f1.x+dx[i]; f2.y=f1.y+dy[i]; if(!inlimit(f2)) continue; vis[f2.x][f2.y]=1; q.push(f2); } } return 0; } int main() { int i,j; while(scanf("%d%d",&n,&m),n|m) { memset(key,0,sizeof(key)); int sx,sy; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++) { scanf("%s",a[i]+1); } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(a[i][j]=='S') { sx=i;sy=j; } if(a[i][j]>='a'&&a[i][j]<='e') key[a[i][j]-'a']++; } } if(bfs(sx,sy)) printf("YES\n"); else printf("NO\n"); } return 0; }