nyoj - 迷宫寻宝(1) 我觉得有点难...我将其改简单一些。
题目描述:与原题基本差不多,但开门条件改一下,每个门只需要一把钥匙即可打开,一把钥匙可以开所有对应的门。
这样就简单很多啦。。。其实只是不想之前写的那个错代码没用处QwQ...
思路:路过钥匙时就将门的状态置为可打开,这样遇到门就可以正常处理了,如果门离起点比钥匙近,比如:
S . A G . . . X . . . . . . . a
就先将门的位置记录到队列中,每次遇到钥匙就将该队列中的门全部拿出来测试。
代码:
#include <bits/stdc++.h>
using namespace std;
struct ss
{
int i, j;
ss() {}
ss(int x, int y) : i(x), j(y) {}
void startpoint(int x, int y) { i = x, j = y; }
};
#define Index(c) ((c) - 'a')
int key[5], dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };
bool bfs(vector<vector<char> > & maze, ss ps)
{
memset(key, 0, sizeof(key));
queue<ss> q, door;
q.push(ps);
while(!q.empty())
{
ps = q.front();
q.pop();
maze[ps.i][ps.j] = 'X';
for (int i = 0; i < 4; i++)
{
ss n(ps.i + dir[i][0], ps.j + dir[i][1]);
char c = 0;
if (n.i > -1 && n.i < maze.size() && n.j > -1 && n.j < maze[0].size())
{
if (maze[n.i][n.j] == 'G')
return true;
c = maze[n.i][n.j];
if (c != 'X')
{
if (c == '.')
q.push(n);
else if (c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e')
{
key[Index(c)] = 1;
while(!door.empty())
{
q.push(door.front());
door.pop();
}
q.push(n);
}
else if (c == 'A' || c == 'B' || c == 'C' || c == 'D' || c == 'E')
{
if (key[Index(c + 32)])
q.push(n);
else
door.push(n);
}
}
}
}
}
return false;
}
int main()
{
int i, j;
while(1)
{
ss ps;
cin >> i >> j;
if (i == 0 && j == 0)
break;
vector<vector<char> > maze(i, vector<char>(j));
for (int i = 0; i < maze.size(); i++)
for( int j = 0; j < maze[0].size(); j++)
{
cin >> maze[i][j];
if (maze[i][j] == 'S')
{
ps.startpoint(i, j);
}
}
if (bfs(maze, ps))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}