迷宫寻宝(一)

难度: 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
来源
POJ月赛改编

#include <bits/stdc++.h>
using namespace std;
char a[30][30];
int b[30][30];
int ss[4][2]={0,1,1,0,0,-1,-1,0};
int s[5];
struct haha{
	int x;
	int y;
};
int main(){
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF&&m+n){
		for(int i=0;i<n;i++)
         scanf("%s",a[i]);
		int x1,y1;
		memset(b,0,sizeof(b));
		memset(s,0,sizeof(s));
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(a[i][j]=='S'){
					x1=i;
					y1=j;
				}
				if(a[i][j]=='a'){
					s[0]++;
				}
				if(a[i][j]=='b'){
					s[1]++;
				}
				if(a[i][j]=='c'){
					s[2]++;
				}
				if(a[i][j]=='d'){
					s[3]++;
				}
				if(a[i][j]=='e'){
					s[4]++;
				}
			}
		}
		int f=0;
		int w;
		while(1){
		queue<haha>q;
		haha e;
		e.x=x1;
		e.y=y1;
		b[x1][y1]=1;
		q.push(e);
		while(!q.empty()){
			haha now=q.front();
			q.pop();
			for(int i=0;i<4;i++){
				int xx=now.x+ss[i][0];
				int yy=now.y+ss[i][1];
				if(a[xx][yy]=='G'){
					f=1;
					break;
				}
				if(xx<0 || xx>=n || yy<0 || yy>=m || a[xx][yy]=='X' || b[xx][yy]==1){
					continue;
				}
				if(a[xx][yy]>='a' && a[xx][yy]<='e'){
					s[a[xx][yy]-'A'-32]--;
					a[xx][yy]='.';
				}
				if(a[xx][yy]>='A' && a[xx][yy]<='E'){
						continue;
				}
				b[xx][yy]=1;
				haha jiu;
				jiu.x=xx;
				jiu.y=yy;
				q.push(jiu);
			}	
		}
		if(f==1){
			break;
		}
		w=0;
		memset(b,0,sizeof(b));
		e.x=x1;
		e.y=y1;
		b[x1][y1]=1;
		q.push(e);
		int t=0;
		while(!q.empty()){
			haha now=q.front();
			q.pop();
			for(int i=0;i<4;i++){
				int xx=now.x+ss[i][0];
				int yy=now.y+ss[i][1];
				if(a[xx][yy]=='G'){
					f=1;
					break;
				}
				if(xx<0 || xx>=n || yy<0 || yy>=m || a[xx][yy]=='X' || b[xx][yy]==1){
					continue;
				}
				if(a[xx][yy]>='a' && a[xx][yy]<='e'){
					s[a[xx][yy]-'A'-32]--;
					a[xx][yy]='.';
				}
			    if(a[xx][yy]>='A' && a[xx][yy]<='E'){
			    	if(s[a[xx][yy]-'A']!=0)
			    		continue;
			    	else{
			    		a[xx][yy]='.';
			    		w=1;
			    	}
				}
				b[xx][yy]=1;
				haha jiu;
				jiu.x=xx;
				jiu.y=yy;
				q.push(jiu);
			}		
		}
		if(w==0 || f==1){
				break;
			}	
	}
		if(f==0){
			printf("NO\n");
		}
		else{
			printf("YES\n");
		}
	}
} 


猜你喜欢

转载自blog.csdn.net/doublekillyeye/article/details/80503715