题意:X代表卫兵,a代表终点,r代表起始点,.代表路,#代表墙,走过.要花费一秒,走过x要花费2秒,求从起点到终点的最少时间。
析:一看到样例就知道是BFS了吧,很明显是最短路径问题,不过又加了一个条件——时间,所以我们用优先队列去优先获取时间短的路径,总体实现起来没有太大难度。
代码如下:
#include <iostream> #include <cstdio> #include <vector> #include <set> #include <queue> #include <iomanip> #include <cstring> #include <sstream> #include <algorithm> #include <map> #include <list> using namespace std; const int maxn = 200 + 10; const int dr[] = {0, 0, 1, -1}; const int dc[] = {1, -1, 0, 0}; struct node{ int r, c, t, d; node() { } node(int rr, int cc, int tt, int dd) : r(rr), c(cc), t(tt), d(dd) { } bool operator < (const node &p) const { if(t != p.t) return t > p.t; return d > p.d; } }; char a[maxn][maxn]; node s, e; int r, c, d[maxn][maxn]; bool is_in(int rr, int cc){ return rr < r && rr >= 0 && cc >= 0 && cc < c; } void bfs(){ priority_queue<node> q; memset(d, -1, sizeof(d)); d[s.r][s.c] = 0; q.push(s); while(!q.empty()){ node u = q.top(); q.pop(); if(u.r == e.r && u.c == e.c){ printf("%d ", u.t); return ; } for(int i = 0; i < 4; ++i){ int x = u.r + dr[i]; int y = u.c + dc[i]; if(is_in(x, y) && a[x][y] == '.' && d[x][y] < 0){ d[x][y] = 1 + d[u.r][u.c]; q.push(node(x, y, u.t+1, u.d+1)); } else if(is_in(x, y) && a[x][y] == 'x' && d[x][y] < 0){ d[x][y] = 1; q.push(node(x, y, u.t+2, u.d+1)); } } } printf("Poor ANGEL has to stay in the prison all his life. "); return ; } int main(){ while(~scanf("%d %d", &r, &c)){ for(int i = 0; i < r; ++i) scanf("%s", a[i]); for(int i = 0; i < r; ++i) for(int j = 0; j < c; ++j) if(a[i][j] == 'r') { s.r = i; s.c = j; s.t = 0; s.d = 0; } else if(a[i][j] == 'a') { e.r = i; e.c = j; e.t = 0; a[i][j] = '.'; } bfs(); } return 0; }