这个题目采用BFS,需要注意以下几点:
1)朋友不止一个,只需要找到所有朋友中到达Angle的最小时间。即可以从a出发找最近的r。
2)由于在有x的地方花费时间是2,其他空地是1.这时需要用到优先队列,每次弹出的是时间最短的节点。
(以后写BFS还是DFS时需要注意先标记再入栈,如果先入栈,弹出时再标记,可能导致同一个节点入栈多次,以后得注意了。在这个位置老是WA)
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<queue>
using namespace std;
#define MAX_SIZE 201
class Point{
public:
Point(){ step = 0; };
short x, y, step;
bool operator<(const Point&a)const{
return step>a.step;
}
};
int N, M;
int dir[4][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
char Map[MAX_SIZE][MAX_SIZE];
bool Isleg(Point &a){
if (a.x < 0 || a.x >= N || a.y < 0 || a.y >= M || Map[a.x][a.y] == '#')
return false;
return true;
}
int BFS(Point pos);
int main(){
Point pos;
int i, j, res;
while (scanf("%d%d", &N, &M) != EOF){
for (i = 0; i < N; i++){
scanf("%s", Map[i]);
for (j = 0; j < M;j++)
if (Map[i][j] == 'a'){
pos.x = i;
pos.y = j;
}
}
res = BFS(pos);
if (res == -1)
printf("Poor ANGEL has to stay in the prison all his life.\n");
else
printf("%d\n", res);
}
return 0;
}
int BFS(Point pos){
priority_queue<Point> Q;
int k;
Point now;
Q.push(pos);
Map[pos.x][pos.y] = '#';
while (!Q.empty()){
pos=Q.top();
Q.pop();
if (Map[pos.x][pos.y] == 'r')
return pos.step;
pos.step++;
for (k = 0; k < 4; k++){
now = pos;
now.x += dir[k][0];
now.y += dir[k][1];
if (Isleg(now)){
if (Map[now.x][now.y] == 'x')
now.step++;
Map[pos.x][pos.y] = '#'; //在进栈之前先要标记,如果在出栈时标记,
//可能导致它再次进栈,导致结果错误
Q.push(now);
}
}
}
return -1;
}