题意:
这道题是常规的BFS,加上了一个”打怪”的设置,而”打怪”实质上就是步数加1的操作罢了.如果用的是queue而不是priority_queue,(我觉得用queue就可以了),得维持”访问的节点的步数递增”这样一个原则,也就是:
如果当前位置是”x”即guard的时候,要打到guard,具体代码中的操作是:
(1)新增加一个该位置的节点push进queue,其中该节点的步数要增加1;
(2)把该位置的”x”修改成例如”.”这样可以走的路.因为如果不修改的话,(1)的过程会不停进行下去,而且从故事的角度而言也是合理的,毕竟guard被打倒,可以理解成”消失”了.另外,做过类似的题目中有”血量”的设置,即怪物血量为k的话,就要停留k秒(或者说步数加k),这样的话,每次进行(2)操作,该数字k就可以变成k-1,来模拟每次打1血的情况,变成0之后,就可以继续走路了.
代码:
// 202ms, 1892K
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
struct Position {
int x, y, step;
Position(int x, int y, int s) : x(x), y(y), step(s) {
}
};
const int FAIL_RETURN_VALUE = -1;
const int DIR[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
const int MAXN(201);
char maze[MAXN][MAXN];
bool isVisited[MAXN][MAXN];
int row, col;
int start_x, start_y;
inline bool isValid(const int &x, const int &y) {
return x >= 0 && y >= 0 && x < row && y < col;
}
int bfs() {
queue<Position> positions;
isVisited[start_x][start_y] = true;
positions.push( Position(start_x, start_y, 0) );
while (!positions.empty()) {
Position cur = positions.front();
positions.pop();
//cout << "(" << cur.x << ", " << cur.y << "):" << cur.step << endl;
if (maze[cur.x][cur.y] == 'a') { // succeed to save ANGEL! so return the least steps
return cur.step;
} else if (maze[cur.x][cur.y] == 'x') { // need to beat the GUARD, so step += 1
positions.push( Position(cur.x, cur.y, cur.step + 1) );
maze[cur.x][cur.y] = '.'; // KEY! It can be explained as 'the GUARD is beaten and then disappear'
continue;
}
for (int dir = 0; dir < 4; ++dir) {
int xx = cur.x + DIR[dir][0];
int yy = cur.y + DIR[dir][1];
if (isValid(xx, yy) && !isVisited[xx][yy] && maze[xx][yy] != '#') { // those which can walk
isVisited[xx][yy] = true;
positions.push( Position(xx, yy, cur.step + 1) );
}
}
}
return FAIL_RETURN_VALUE;
}
int main() {
// freopen("in.txt", "r", stdin);
while (cin >> row >> col) {
memset(isVisited, false, sizeof isVisited);
for (int i(0); i < row; ++i) {
for (int j(0); j < col; ++j) {
cin >> maze[i][j];
if (maze[i][j] == 'r') {
start_x = i;
start_y = j;
}
}
}
int result = bfs();
if (result == FAIL_RETURN_VALUE) {
cout << "Poor ANGEL has to stay in the prison all his life." << endl;
} else {
cout << result << endl;
}
}
return 0;
}