题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026
思路:
此题与普通的迷宫题差异主要在以下两个方面:
(1).存在monster。所以普通队列得到的答案不一定是整体的最优解。
(2).需要输出路径。
第一点:使用自定义优先级的优先队列即可解决。
第二点:使用结构体(或二维数组)来记录路径。但为了避免被可以通过但明显不是最优解的状态将最优解的路径所覆盖掉,我们需要在覆盖路径是加个条件:
if(a.t<road[b.x][b.y].t){ //如果当前能到达b点的状态a的时间 小于 b点记录的前一个状态的时间少 则转移
road[b.x][b.y].x = a.x;
road[b.x][b.y].y = a.y;
road[b.x][b.y].t = a.t;
}
另外注意输出路径的顺序,我们是从后往前记录,但需要从前往后的输出。
所以使用队列或者递归输出即可
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 105;
const int INF = 1e8;
struct P{
int x,y;
int t;
friend bool operator<(P a,P b){
return a.t > b.t;
}
}road[maxn][maxn];
int n,m,maze[maxn][maxn],vis[maxn][maxn];
int sx,sy,gx,gy,tt;
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
bool check(int xx,int yy){
if(xx<0 || xx>=n || yy<0 || yy>=m || maze[xx][yy] == -1 || vis[xx][yy])
return true;
return false;
}
int bfs(void){
sx = sy = 0;
gx = n - 1;
gy = m - 1;
priority_queue<P> que;
P a,b;
a.x = sx;
a.y = sy;
a.t = 0;
vis[a.x][a.y] = 1;
que.push(a);
while(que.size()){
int i,j;
a = que.top();
que.pop();
if(a.x == gx && a.y == gy){
return a.t;
}
for(i=0 ;i<4 ;i++){
b.x = a.x + dx[i];
b.y = a.y + dy[i];
if(check(b.x,b.y)){
continue;
}
b.t = a.t + 1 + maze[b.x][b.y];
if(a.t<road[b.x][b.y].t){
road[b.x][b.y].x = a.x;
road[b.x][b.y].y = a.y;
road[b.x][b.y].t = a.t;
}
vis[b.x][b.y] = 1;
que.push(b);
}
}
return -1;
}
void output(int xx,int yy){
if(xx == 0 && yy == 0){
printf("%ds:(0,0)->",tt++);
return;
}
output(road[xx][yy].x,road[xx][yy].y);
printf("(%d,%d)\n",xx,yy);
while(maze[xx][yy]>0){
printf("%ds:FIGHT AT (%d,%d)\n",tt++,xx,yy);
maze[xx][yy]--;
}
if(!(xx==n-1 && yy==m-1)){
printf("%ds:(%d,%d)->",tt++,xx,yy);
}
}
int main(){
while(scanf("%d%d",&n,&m) != EOF){
char ch;
int i,j;
for(i=0 ;i<n ;i++){
for(j=0 ;j<m ;j++){
road[i][j].t = INF;
vis[i][j] = 0;
cin >> ch;
if(ch == 'X')
maze[i][j] = -1;
else if(ch == '.')
maze[i][j] = 0;
else{
maze[i][j] = ch - '0';
}
}
}
int tem = bfs();
if(tem == -1){
printf("God please help our poor hero.\n");
}
else{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",tem);
tt = 1;
output(n-1,m-1);
}
printf("FINISH\n");
}
return 0;
}