迷宫寻宝(一)
时间限制:
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
题解:
- num记录钥匙的个数;神搜,搜到钥匙就加上,遇到门就判断,带个回溯;但是不知道对不对,还在判题中;
- bfs代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 #define mem(x) memset(x,0,sizeof(x)) 5 using namespace std; 6 char map[25][25]; 7 int vis[25][25]; 8 int key[10]; 9 int disx[4]={0,0,1,-1}; 10 int disy[4]={1,-1,0,0}; 11 int M,N; 12 struct Node{ 13 int x,y; 14 }; 15 bool limit(Node a){ 16 if(map[a.x][a.y]>='a'&&map[a.x][a.y]<='e')key[map[a.x][a.y]-'a']--; 17 if(map[a.x][a.y]=='G')return true; 18 return false; 19 } 20 void bfs(int sx,int sy){ 21 queue<Node>dl; 22 Node a,b; 23 vis[sx][sy]=1; 24 a.x=sx;a.y=sy; 25 dl.push(a); 26 while(!dl.empty()){ 27 a=dl.front(); 28 dl.pop(); 29 if(limit(a)){ 30 puts("YES"); 31 return ; 32 } 33 if(map[a.x][a.y]>='A'&&map[a.x][a.y]<='E'){ 34 if(!key[map[a.x][a.y]-'A'])map[a.x][a.y]='.'; 35 else{ 36 if(dl.empty())break; 37 dl.push(a); 38 continue; 39 } 40 } 41 for(int i=0;i<4;i++){ 42 b.x=a.x+disx[i]; 43 b.y=a.y+disy[i]; 44 if(b.x<0||b.y<0||b.x>=M||b.y>=N||vis[b.x][b.y]||map[b.x][b.y]=='X')continue; 45 vis[b.x][b.y]=1; 46 dl.push(b); 47 } 48 } 49 puts("NO"); 50 } 51 int main(){ 52 while(scanf("%d%d",&M,&N),M|N){ 53 mem(vis);mem(key); 54 for(int i=0;i<M;i++)scanf("%s",map[i]); 55 int sx,sy; 56 for(int x=0;x<M;x++)for(int y=0;y<N;y++){ 57 if(map[x][y]>='a'&&map[x][y]<='e')key[map[x][y]-'a']++; 58 if(map[x][y]=='S')sx=x,sy=y; 59 } 60 bfs(sx,sy); 61 } 62 return 0; 63 }