迷宫寻宝(一)
时间限制:
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
这一道题需要用到广搜,对门的处理。如果能找齐钥匙,就把门踏平,不能,就重新入队,难点就在此.
源码:
#include <iostream>
#include <queue>
#include <memory.h>
using namespace std;
int key[5];
char map[100][100];
bool vis[100][100];
int startx, starty;
int n, m;
struct node
{
int x;
int y;
};
bool judge(int x, int y);
bool dfs(int startx,int starty);
int main()
{
int i, j;
while (1)
{
memset(key,0,sizeof(key));
cin >> m >> n;
if (!m && !n)
break;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
{
cin >> map[i][j];
if (map[i][j] == 'S')
{
startx = i;
starty = j;
}
else if (map[i][j] >= 'a'&&map[i][j] <= 'e')
key[map[i][j] - 'a'] ++;
}
if (dfs(startx, starty))
cout << "YES" << endl;
else
cout << "NO"<< endl;
}
return 0;
}
bool judge(int x, int y)
{
if (x < 0 || x >= m || y < 0 || y >= n || vis[x][y])
return false;
else if (map[x][y] == 'X')
return false;
else if (map[x][y] >= 'a'&&map[x][y] <= 'e')
key[map[x][y] - 'a'] --;
return true;
}
bool dfs(int startx, int starty)
{
queue<node> p;
node n1, n2;
node next[4] = { {1,0},{-1,0},{0,1},{0,-1} };
n1.x = startx;
n1.y = starty;
memset(vis,false,sizeof(vis));
p.push(n1);
vis[n1.x][n1.y] = true;
while (!p.empty())
{
n2 = p.front();
p.pop();
if (map[n2.x][n2.y] == 'G')
return true;
else if (map[n2.x][n2.y] >= 'A'&&map[n2.x][n2.y] <= 'E')
{
if (key[map[n2.x][n2.y] - 'A'] == 0)
map[n2.x][n2.y] = '.';
else
{
if (p.empty())
return false;
else
{
p.push(n2);
continue;
}
}
}
for (int i = 0; i < 4; i++)
{
n1.x = n2.x + next[i].x;
n1.y = n2.y + next[i].y;
if (judge(n1.x, n1.y))
{
p.push(n1);
vis[n1.x][n1.y] = true;
}
}
}
return false;
}