nyoj 82

迷宫寻宝(一)

时间限制: 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;
}

你可能感兴趣的:(迷宫,广搜,南阳理工acm)