题目链接: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; }