题目链接:POJ 2312 Battle City
打碎砖头需要两步,这里如果直接加到普通的队列中可以说是违反了BFS的规则,所以需要使用优先队列来选择当前队列中步数最少的那个,画画图就很明白了。
记得要清空队列。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int MAX_N = 300 + 10;
const int INF = (1 << 29);
struct Point
{
int x, y, dis;
friend bool operator < (Point a, Point b)
{
return a.dis > b.dis;
}
Point (int x, int y, int dis) : x(x), y(y), dis(dis) {};
Point () {};
};
priority_queue <Point> Q;
int vis[MAX_N][MAX_N];
char _map[MAX_N][MAX_N];
int fx[4] = {0, 1, 0, -1};
int fy[4] = {1, 0, -1, 0};
int N, M, res;
void BFS()
{
int dx, dy;
Point a;
while(!Q.empty())
{
a = Q.top();
if(_map[a.x][a.y] == 'T')
{
res = a.dis;
return ;
}
Q.pop();
for(int i = 0; i < 4; i++)
{
dx = a.x + fx[i], dy = a.y + fy[i];
if(dx >= 0 && dy >= 0 && dx < N && dy < M && !vis[dx][dy] && _map[dx][dy] != 'S' && _map[dx][dy] != 'R')
{
vis[dx][dy] = 1;
if(_map[dx][dy] == 'B')
Q.push(Point(dx, dy, a.dis + 2));
else
Q.push(Point(dx, dy, a.dis + 1));
}
}
}
}
int main()
{
while(scanf("%d%d", &N, &M), N + M)
{
memset(vis, 0, sizeof(vis));
res = INF;
for(int i = 0; i < N; i++)
{
scanf("%s", _map[i]);
for(int j = 0; j < M; j++)
{
if(_map[i][j] == 'Y')
{
vis[i][j] = 1;
Q.push(Point(i, j, 0));
}
}
}
BFS();
if(res == INF)
printf("-1\n");
else
printf("%d\n", res);
while(!Q.empty())
Q.pop();
}
return 0;
}