1159:Maze
输出
样例输入
4 4
S.X.
a.X.
..XG
....
3 4
S.Xa
.aXB
b.AG
0 0
样例输出
YES
NO
题意:从S走到G,中间X是墙,‘.’是路,A-E是门,a-e是门的钥匙,要想进入门必须要找到所有的钥匙。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stdlib.h>
using namespace std;
int w[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
char map[23][23];
int v[23][23];
int n,m;
struct zz //记录搜索坐标
{
int x;
int y;
}xs,ls;
struct md
{
int x; // x,y记录门的坐标
int y;
int v; //标记钥匙是否收集齐
int v1; //标记是否能到门
int g; //该门钥匙总数
int z; //收集到该门钥匙数
}door[8];
void bfs(int x,int y) //bfs
{
queue<zz>q;
xs.x=x;
xs.y=y;
v[x][y]=1;
q.push(xs);
while(!q.empty())
{
xs=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int xx=xs.x+w[i][0];
int yy=xs.y+w[i][1];
if(xx<n&&xx>=0&&yy>=0&&yy<m&&v[xx][yy]!=1&&map[xx][yy]!='X')
{
if(map[xx][yy]<='e'&&map[xx][yy]>='a')
{
ls.x=xx;
ls.y=yy;
v[xx][yy]=1;
q.push(ls);
door[map[xx][yy]-'a'].z++;
if(door[map[xx][yy]-'a'].g==door[map[xx][yy]-'a'].z) //钥匙集齐
{
door[map[xx][yy]-'a'].v1=1; //标记钥匙收集齐
if(door[map[xx][yy]-'a'].v==1) //判断是否能走到门
{ ls.x=door[map[xx][yy]-'a'].x;
ls.y=door[map[xx][yy]-'a'].y;
v[ls.x][ls.y]=1;
q.push(ls);
}
}
}
else if(map[xx][yy]>='A'&&map[xx][yy]<='E') //走到门
{
door[map[xx][yy]-'A'].v=1; //标记走到了门
if(door[map[xx][yy]-'A'].v1==1) //判断是否收集齐了钥匙
{
ls.x=xx;
ls.y=yy;
v[xx][yy]=1;
q.push(ls);
}
}
else if(map[xx][yy]=='.')
{
ls.x=xx;
ls.y=yy;
v[xx][yy]=1;
q.push(ls);
}
else if(map[xx][yy]=='G') //出去条件
{
printf("YES\n");
return ;
}
}
}
}
printf("NO\n");
}
int main ()
{
while(scanf("%d%d",&n,&m),n!=0||m!=0)
{ int xx,yy;
memset(v,0,sizeof(v));
memset(map,0,sizeof(map));
for(int i=0;i<8;i++)
{ door[i].v1=0;
door[i].v=0;
door[i].z=0; //初始化
door[i].g=0;
}
for(int i=0;i<n;i++)
{
scanf("%s",&map[i]);
for(int j=0;j<m;j++)
{
if(map[i][j]<='e'&&map[i][j]>='a')
{
door[map[i][j]-'a'].g++; //记录钥匙有几个才能打开门
}
else if(map[i][j]=='S')
{
xx=i; //记录起点
yy=j;
}
else if(map[i][j]<='E'&&map[i][j]>='A')
{
door[map[i][j]-'A'].x=i;
door[map[i][j]-'A'].y=j; //记录门所在位置
}
}
}
getchar();
bfs(xx,yy);
}
return 0;
}