这题,简单的BFS就可以搞定。题目的大概意思是最短时间从地图的r到达a。
一开始,用普通的队列来做,结果内存超了,原因是N和M最大200;普通的队列会浪费一大堆内存,所以应该改用优先队列来做。
下面是AC的代码:
#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
class data
{
public:
int x, y, cost;
friend bool operator < (data a, data b) //按最小堆来建堆
{
return b.cost < a.cost;
}
};
int N, M;
char map[205][205];
int sx, sy, ex, ey;
int xy[4][2] = {1,0,-1,0,0,1,0,-1};
int bfs() //BFS搜索地图,走过的标记为#
{
priority_queue<data>que;
data temp;
temp.x = sx; temp.y = sy; temp.cost = 0;
que.push(temp);
map[sx][sy] = '#';
while(!que.empty())
{
temp = que.top();
que.pop();
if(temp.x == ex && temp.y == ey)
return temp.cost;
int fx, fy;
for(int i = 0; i < 4; i++) //四个方向搜索
{
fx = temp.x + xy[i][0];
fy = temp.y + xy[i][1];
if(fx >= 0 && fx < N && fy >= 0 && fy < M && map[fx][fy] != '#') //判断是否符号条件
{
if(map[fx][fy] == '.' || map[fx][fy] == 'a') //判断是否是卫兵,
{
data te;
te.x = fx; te.y = fy; te.cost = temp.cost + 1;
que.push(te);
map[fx][fy] = '#';
}
else //是卫兵,需要两个单位时间
{
data te;
te.x = fx; te.y = fy; te.cost = temp.cost + 2;
que.push(te);
map[fx][fy] = '#';
}
}
}
}
return -1;
}
int main()
{
freopen("data.txt", "r", stdin);
while(scanf("%d%d", &N, &M) != EOF)
{
getchar();
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
scanf("%c", &map[i][j]);
if(map[i][j] == 'r')
{
sx = i;
sy = j;
}
if(map[i][j] == 'a')
{
ex = i;
ey = j;
}
}
getchar();
}
int ans = bfs();
if(ans == -1)
printf("Poor ANGEL has to stay in the prison all his life.\n");
else
printf("%d\n", ans);
}
return 0;
}