迷宫寻宝(一)
时间限制:
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
/* 一路抄袭。终于原创了一次了,尼玛。。。。。不过看了下思路。先广搜,等钥匙找全之后再从头开始进行广搜,不断广搜。。。 加油!!! Time:2014-10-27 17:38 */ #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; #define MAX 22 struct Point{ int x,y; }S,E; char map[MAX][MAX]; bool vis[MAX][MAX]; int N,M; int kNum[6]; bool door[6]; int move[4][2]={1,0,0,1,-1,0,0,-1}; bool Judge(Point a){ if(map[a.x][a.y]!='X'&&a.x>=0&&a.x<N&&a.y>=0&&a.y<M) return true; return false; } bool BFS(){ queue<Point>q; int key; q.push(S);vis[S.x][S.y]=1; Point temp,cur,gate[6]; while(!q.empty()){ cur=q.front();q.pop(); for(int i=0;i<4;i++){ temp=cur; temp.x+=move[i][0]; temp.y+=move[i][1]; if(!vis[temp.x][temp.y]&&Judge(temp)){ //printf("%d %d\n",temp.x,temp.y); vis[temp.x][temp.y]=true; if(map[temp.x][temp.y]>='A'&&map[temp.x][temp.y]<='E'){ key=map[temp.x][temp.y]-'A'; gate[key]=temp; if(door[key]){ q.push(temp); map[temp.x][temp.y]='.';//开门 } }else if(map[temp.x][temp.y]>='a'&&map[temp.y][temp.y]<='e'){ q.push(temp); key=map[temp.x][temp.y]-'a'; map[temp.x][temp.y]='.';//注意和上一行的前后顺序 kNum[key]--; // printf("key=%d %d\n",key,kNum[key]); if(kNum[key]==0){ door[key]=true; memset(vis,0,sizeof(vis)); while(!q.empty())q.pop(); q.push(S);vis[S.x][S.y]=true; } }else if(map[temp.x][temp.y]=='.'){ q.push(temp); }else if(map[temp.x][temp.y]=='G') return true; } } } return false; } int main(){ int i,j; while(scanf("%d%d",&N,&M)!=EOF){ if(N==0&&M==0) break; memset(kNum,0,sizeof(kNum)); memset(vis,0,sizeof(vis)); memset(map,0,sizeof(map)); memset(door,0,sizeof(door)); for(i=0;i<N;i++){ scanf("%s",map[i]); for(j=0;j<M;j++){ if(map[i][j]>='a'&&map[i][j]<='e'){ kNum[map[i][j]-'a']++; }else if(map[i][j]=='S'){ S.x=i;S.y=j; }else if(map[i][j]=='G'){ E.x=i;E.y=j; } } } //printf("%d\n",kNum[0]); if(BFS())printf("YES\n"); else printf("NO\n"); } return 0; }
-
输入可能会有多组测试数据(不超过10组)。