HDU杭电1026 Ignatius and the Princess I(迷宫问题bfs)

题目地址: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;
}






你可能感兴趣的:(ACM**搜索*******,ACM**图论*******)