题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1026
题意,x代表不能走的路,小点 代表可以走的路,数字代表需要在此处停留的步数(时间)。
BFS广搜即可。但这个题有一个值得关注的地方,他需要在数字处停留几步来打怪,那么有一个问题是:步数最少找到出口的方案,会因为打怪而时间(或者说步数)变长,就有可能不在是最短时间。
我们知道bfs广搜是横向搜索一棵树,最先搜到出口的树的那一层,一定是距离最近的走路方案,但这个题会因为打怪而延长时间,因此需要用到优先队列。
(优先队列的定义可以百度)
优先队列的作用是,对树的每一层搜索时,最先搜索当前步数最少的那个方向。
(就是每一次循环去找下一步之前,对队列中的所有元素按时间(步数)排序)。
还有一个难点是输出,本题要求输出路径,不仅仅输出步数(时间)。
这个的处理,我是用了记录前驱的方法,即在每一个点,记录下上一步所在的点,最后再往回退,推到起点。
为了方便记录路径,这个题我没有用STL库的队列,是自己定义的数组代替数列(这样就可以留下每一步的路径,方便记录路径,如果用C++里的queue队列,也未尝不可,记录路径也可以用一个二维数组来记录每一个点的上一步是哪里,从终点往回退)
/*************
代码如下:
#include
#include
#include
using namespace std;
struct point{
int last;//记录上一步从哪里来
int x,y; //坐标
int step;//记录当前的步数
int HP;//记录小怪血量(即 需要停留多久)
};
int dir[4][2]={0,1,1,0,-1,0,0,-1};//控制方向。
point path[101010]; //用来代替队列的数组
char map[110][110];
int N,M;
int cmp(point a,point b)//模拟优先队列的功能,(按步数排序)
{
if(a.step=0&&v.x=0&&v.y(%d,%d)\n",v.step-v.HP, u.x,u.y, v.x,v.y);
if(v.HP>0) //有野怪
{
for(int i=v.HP;i>0;i--)
{
printf("%ds:FIGHT AT (%d,%d)\n",v.step-i+1,v.x,v.y);
}
}
}
int main()
{
while(~scanf("%d%d",&N,&M))
{
for(int i=0;i=0)
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",path[v].step);
output(v);
}
else
{
puts("God please help our poor hero.");
}
puts("FINISH");
}
return 0;
}