原题连接:http://acm.hdu.edu.cn/showproblem.php?pid=1026
题意: 给一个 n * m 的矩阵,X 代表墙 . 代表路,若是数字 ,则该点有 怪,需要 打怪。从求 从(0,0 )点 到 (n-1,m-1)点的用时最小的路,要输出路径。
思路:1:求用时最小路----BFS(广搜)+ 优先队列;
2:在搜到一个点时对应记录前一个点的坐标!,同时 标记该点(不能再次搜到);
3:搜到终点后 从终点 一次向前 找前一个点的坐标,入栈!!
4:依次出栈,即是 路径!!
这个题做了一下午呀,第一次遇到要记录路径的广搜,伤脑筋。。。AC代码:
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;
int map[150][150];
int sx[]={1,-1,0,0},zy[]={0,0,1,-1};
struct hello
{
friend bool operator< (hello n1, hello n2)
{
return n1.step > n2.step;
}
int x,y;
int step;
};
struct sb
{
int x,y;
int f;
}ac[150][150];
struct fuck
{
int x,y;
int xs,ys;
int step;
int stop;
};
void find_path(int n,int m,int step)
{
int a,b;
stack<fuck> S;
while(step&&n>=0&&m>=0)
{
//printf("%d %d--------------- %d %d\n",n,m,ac[n][m].x,ac[n][m].y);
if(ac[n][m].f==0)
{
fuck t1={n,m,ac[n][m].x,ac[n][m].y,step,0};
step--;
S.push(t1);
}
else
{
fuck t1={n,m,ac[n][m].x,ac[n][m].y,step-ac[n][m].f,ac[n][m].f};
step-= ac[n][m].f;
step--;
S.push(t1);
}
a=n;b=m;
n=ac[a][b].x;
m=ac[a][b].y;
}
while(!S.empty())
{
fuck t1;
t1.x=S.top().x;
t1.y=S.top().y;
t1.step=S.top().step;
t1.stop=S.top().stop;
t1.xs=S.top().xs;
t1.ys=S.top().ys;
printf("%ds:(%d,%d)->(%d,%d)\n",t1.step,t1.xs-1,t1.ys-1,t1.x-1,t1.y-1);
while(t1.stop--)
{
printf("%ds:FIGHT AT (%d,%d)\n",++t1.step,t1.x-1,t1.y-1);
}
S.pop();
}
printf("FINISH\n");
}
void bfs(int n,int m)
{
int a,b,x,y,i,j,k,step,loop=0;
priority_queue<hello> Q;
hello t1={1,1,0};
Q.push(t1);
map[1][1]=0;
while(!Q.empty())
{
x= Q.top().x;
y= Q.top().y;
step= Q.top().step;
Q.pop();
if(x==n&&y==m)
{loop=1;break;}
if(loop==1)
break;
for(a=0;a<4;a++)
{
i= x+sx[a];
j= y+zy[a];
if(map[i][j]!=0)
{
//printf("***%d %d**---------------**%d %d\n",x,y,i,j);
if(map[i][j]==20)
{
ac[i][j].x=x;
ac[i][j].y=y;
ac[i][j].f=0;
hello t2={i,j,step+1};
Q.push(t2);
}
else if(map[i][j]>=1&&map[i][j]<=9)
{
ac[i][j].x=x;
ac[i][j].y=y;
ac[i][j].f=map[i][j];
hello t2={i,j,step+1+map[i][j]};
Q.push(t2);
}
map[i][j]=0;
}
}
}
if(loop==0)
printf("God please help our poor hero.\nFINISH\n");
else
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",step);
find_path(n,m,step);
}
}
int main()
{
int a,b,n,m;
while(~scanf("%d%d",&n,&m))
{
getchar();
memset(map,0,sizeof(map));
char ch;
for(a=1;a<=n;a++)
{
for(b=1;b<=m;b++)
{
scanf("%c",&ch);
if(ch>='1'&&ch<='9')
map[a][b]=ch-'0';
else if(ch=='.')
map[a][b]=20;
}
getchar();
}
if(map[n][m]==0)
printf("God please help our poor hero.\nFINISH\n");
else
bfs(n,m);
}
}