题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026
题目解析:保存上当前结点的上一个结点,然后深搜打印路径。
代码如下:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int x;
int y;
int step;
friend bool operator<(node n1,node n2)
{
return n1.step>n2.step; //将队列里面步数小的先出队列
}
};
struct lujing //保存下路径
{
int x;
int y;
}LJ[109][109];
char map[109][109];
int vis[109][109];
int path[109][109];
int m,n;
int begin_x,begin_y,end_x,end_y;
int dx[5]={1,-1,0,0};
int dy[5]={0,0,1,-1};
bool judge(int x,int y)
{
if(x>=0&&x<m&&y>=0&&y<n&&map[x][y]!='X'&&!vis[x][y])
return true;
return false;
}
int bfs()
{
node n1,n2;
priority_queue<node>q;
memset(vis,0,sizeof(vis));
memset(path,0,sizeof(path));
memset(LJ,0,sizeof(LJ));
n1.x=begin_x;
n1.y=begin_y;
n1.step=0;
if(map[n1.x][n1.y]>='1'&&map[n1.x][n1.y]<='9')
n1.step+=map[n1.x][n1.y]-'0';
q.push(n1);
vis[n1.x][n1.y]=1;
while(!q.empty())
{
n2=q.top();
q.pop();
if(n2.x==end_x&&n2.y==end_y)
return n2.step;
for(int i=0;i<4;i++)
{
n1.x=n2.x+dx[i];
n1.y=n2.y+dy[i];
if(judge(n1.x,n1.y))
{
if(map[n1.x][n1.y]=='.')
n1.step=n2.step+1;
else
n1.step=n2.step+1+map[n1.x][n1.y]-'0';
q.push(n1);
vis[n1.x][n1.y]=1;
LJ[n1.x][n1.y].x=n2.x;
LJ[n1.x][n1.y].y=n2.y; //保存当前结点的前一个结点
path[n1.x][n1.y]=n1.step; //保存当前点的步数
}
}
}
return -1;
}
void find(int x,int y) //递归回溯打印路径
{
if(x==0&&y==0)
return;
find(LJ[x][y].x,LJ[x][y].y);
printf("%ds:(%d,%d)->(%d,%d)\n",path[LJ[x][y].x][LJ[x][y].y]+1,LJ[x][y].x,LJ[x][y].y,x,y);
if(map[x][y]!='.')
{
for(int i=1;i<=map[x][y]-'0';i++)
{
printf("%ds:FIGHT AT (%d,%d)\n",path[LJ[x][y].x][LJ[x][y].y]+i+1,x,y);
}
}
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
for(int i=0;i<m;i++)
scanf("%s",map[i]);
begin_x=0;
begin_y=0;
end_x=m-1;
end_y=n-1;
int s=bfs();
if(s>0)
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",s);
find(m-1,n-1);
}
else
printf("God please help our poor hero.\n");
printf("FINISH\n");
}
return 0;
}