hdu 1026 Ignatius and the Princess I(BFS + 优先级队列 + 路径输出)
题目链接: hdu 1026 Ignatius and the Princess I
题目描述: 从左上角走到右下角,“.”表示可以走,“X”表示不能走,“1-9”表示走到这里需要额外的时间,走一步1s,问最后的时间和路径。
题解思路: 因为问的是最优解,所以考虑用BFS来写,然后由于有数组格子会有额外的时间,所以就需要用到优先级队列,路径输出只要用一个path数组记录每一的走过的点从上一个点走过来的方式标号,因为要正序打印路径,所有用递归来写输出路径的函数就可以了。
代码如下:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int m, n;
int ans = INF;
#define is(x, y) (x >= 0 && x < m && y >= 0 && y < n)
struct node{
int x, y;
int step;
friend bool operator < (node a, node b){
return a.step > b.step;
}
};
int d[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
char dt[105][105];
int num[105][105];
int vis[105][105];
int path[105][105];
void bfs()
{
priority_queue<node> q;
node s;
s.x = s.y = 0;
s.step = 0;
vis[0][0] = 1;
q.push(s);
while(!q.empty()){
node temp = q.top();
q.pop();
if(temp.x == m - 1 && temp.y == n - 1){
ans = temp.step;
return;
}
for(int i = 0; i < 4; i++){
node tt;
int dx = temp.x + d[i][0];
int dy = temp.y + d[i][1];
if(!vis[dx][dy] && is(dx, dy) && dt[dx][dy] != 'X'){
tt.x = dx;
tt.y = dy;
tt.step = temp.step + 1 + num[dx][dy];
path[dx][dy] = i + 1;
vis[dx][dy] = 1;
q.push(tt);
}
}
}
}
int cnt = 1;
void print(int x, int y)
{
if(path[x][y] == 0){
return;
}
int dx = x - d[path[x][y] - 1][0];
int dy = y - d[path[x][y] - 1][1];
print(dx, dy);
printf("%ds:(%d,%d)->(%d,%d)\n", cnt++, dx, dy, x, y);
while (num[x][y]--)
{
printf("%ds:FIGHT AT (%d,%d)\n", cnt++, x, y);
}
}
int main()
{
while(~scanf("%d%d", &m, &n)){
memset(num, 0, sizeof(num));
memset(vis, 0, sizeof(vis));
memset(path, 0, sizeof(path));
ans = INF;
cnt = 1;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cin >> dt[i][j];
if(dt[i][j] == '.'){
num[i][j] = 0;
}
if(dt[i][j] == 'X'){
num[i][j] = -1;
}
if(dt[i][j] - '0' >= 1 && dt[i][j] - '0' <= 9){
num[i][j] = dt[i][j] - '0';
}
}
}
bfs();
if(ans != INF){
printf("It takes %d seconds to reach the target position, let me show you the way.\n", ans);
print(m - 1, n - 1);
}
else{
cout << "God please help our poor hero.\n";
}
printf("FINISH\n");
}
return 0;
}