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;
}