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; }