/**
时间限制: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
*/
#include <iostream>
#include <map>
#include <queue>
#include <cstdio>
#include <memory.h>
#include <ctime>
#define S 30
using namespace std;
typedef pair<int,int>point;
queue<point>que;
int N,M,sx,sy;
char maze[S][S];
int vis[S][S],key[5];
const int dirx[4]={-1,1,0,0},diry[4]={0,0,-1,1};
vector<point>door[5];
bool bfs(){
point cur,next;
int acquire[5]={0};
while(que.size()){
cur = que.front();
que.pop();
int cx = cur.first,cy = cur.second;
for(int i=0;i<4;i++){
int nx = cx+dirx[i] , ny = cy+diry[i];
char ch = maze[nx][ny];
if(nx>=0&&nx<N&&ny>=0&&ny<M&&ch!='X'&&!vis[nx][ny]){
if(ch=='.'){
vis[nx][ny] = 1;
que.push(make_pair(nx,ny));
}
else if(ch>='a'&&ch<='e'){
vis[nx][ny] = 1;
acquire[ch-'a']++;
que.push(make_pair(nx,ny));
while(key[ch-'a']==acquire[ch-'a']&&!door[ch-'a'].empty()){
que.push(door[ch-'a'].back());
door[ch-'a'].pop_back();
}
}
else if(ch>='A'&&ch<='E'){
int t = ch-'A';
if(acquire[t]!=key[t]){
door[t].push_back(make_pair(nx,ny));
vis[nx][ny] = 1;
}
else{
vis[nx][ny] = 1;
que.push(make_pair(nx,ny));
}
}
else if(ch=='G') return true;
}
}
}
return false;
}
int main(){
while(scanf("%d %d",&N,&M)&&(N||M)){
getchar();
memset(key,0,sizeof(key));
memset(vis,0,sizeof(vis));
memset(door,0,sizeof(door));
while(que.size()) que.pop();
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
scanf("%c",&maze[i][j]);
if(maze[i][j]=='S'){
sx = i;
sy = j;
}
else if(maze[i][j]>='a'&&maze[i][j]<='e'){
int t = maze[i][j] - 'a';
key[t]++;
}
}
getchar();
}
vis[sx][sy] = 1;
que.push(make_pair(sx,sy));
if(bfs()) printf("YES\n");
else printf("NO\n");
}
return 0;
}