题目大意:给一个迷宫,需要从左上角走到右下角,某些格子会有一些数字,经过的时候会增加相应数字对应的时间,求最短时间以及整个过程的路径输出。
解题思路:这个题纠结了好久呀,题不难,主要是路径的输出上太麻烦了,始终都调试不对。后边看了下大牛的题解,然后才A了。这个题直接就是简单的BFS,只不过要求路径输出,因此中间要用结构体记录路径。这里用一个二维的结构体记录对应点的前去结点以及该点所需要的时间。然后对结果进行递归输出即可,详见code。
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1026
code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 100+10;
int n,m;
char map[MAXN][MAXN];
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct node{
int x,y,time;
friend bool operator<(node a, node b){return a.time > b.time;}
}path[MAXN][MAXN];
int BFS(){
node s,t;
s.x=s.y=0;s.time=0;
priority_queue<node> Q;
Q.push(s);
while(!Q.empty()){
s= Q.top(); Q.pop();
if(s.x==n-1 && s.y==m-1) return s.time;
for(int i = 0; i < 4; ++i){
t=s;
t.x+=dir[i][0];
t.y+=dir[i][1];
if(t.x>=0 && t.x<n && t.y>=0 && t.y<m && map[t.x][t.y]!='X'){ //边界以及条件判断
++t.time;
path[t.x][t.y].x = s.x; //记录前驱结点
path[t.x][t.y].y = s.y;
path[t.x][t.y].time = 0; //为‘.’时,时间即为0
if(map[t.x][t.y] != '.'){ //否则时间记录为数值
t.time += map[t.x][t.y] - '0';
path[t.x][t.y].time = map[t.x][t.y] - '0';
}
map[t.x][t.y] = 'X'; //访问过后标记
Q.push(t);
}
}
}
return -1;
}
void print(int x,int y,int cnt){ //递归打印
if(cnt==0) return ;
cnt-=path[x][y].time;
print(path[x][y].x,path[x][y].y,cnt-1);
printf("%ds:(%d,%d)->(%d,%d)\n",cnt++,path[x][y].x,path[x][y].y,x,y);
while(path[x][y].time--) //打怪的输出
printf("%ds:FIGHT AT (%d,%d)\n",cnt++,x,y);
}
int main(){
//freopen("input.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF){
memset(path,0,sizeof(path));
for(int i=0;i<n;i++)
scanf("%s",map[i]);
int cnt=BFS();
if(cnt==-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",cnt);
print(n-1,m-1,cnt); //递归打印
}
printf("FINISH\n");
}
return 0;
}