标签:break 迷宫 编写 mem star 程序 size char 列存储
题目:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=82
2018-06-23 23:44:05 p.s.刚重新读了一下题,貌似自己看漏了:
描述
一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫里有N个编过号的门(N<=5),它们分别被编号为A,B,C,D,E.为了找到宝藏,ACM必须打开门,但是,开门之前必须在迷宫里找到这个打开这个门所需的所有钥匙(每个门都至少有一把钥匙),例如:现在A门有三把钥匙,ACM就必须找全三把钥匙才能打开A门。现在请你编写一个程序来告诉ACM,他能不能顺利的得到宝藏。
这里重点是开门前必须找到所有这个门对应的钥匙 orz。。。
思路:虽然不知道为啥没有AC掉...难道一把钥匙只能用一次?假如是这样的话那就还得再改改...目前算法沿用了迷宫问题的算法,但难点在于,假如门比钥匙离宝藏比较近,算法就没有将门的点加入队列,所以需要再维护一个队列存储那些还没有得到钥匙的门,然后,每当拿到一个钥匙就将队列中的所有门拿出来测试。。。例如下面这样的情况:
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; }
标签:break 迷宫 编写 mem star 程序 size char 列存储
原文地址:https://www.cnblogs.com/darkchii/p/9215922.html