【优先队列广搜+前驱记录】HDU 1026 Ignatius and the Princess I_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > 【优先队列广搜+前驱记录】HDU 1026 Ignatius and the Princess I

【优先队列广搜+前驱记录】HDU 1026 Ignatius and the Princess I

 2011/9/2 8:03:48  基德KID.1412  http://972169909-qq-com.iteye.com  我要评论(0)
  • 摘要:http://acm.hdu.edu.cn/showproblem.php?pid=1026题意:问从图的左上角到达右下角需要的最短时间,如果格子是数字n(1-9),说明有怪兽,要打死他花费n的时间SampleInputSampleOutputIttakes13secondstoreachthetargetposition,letmeshowyoutheway.1s:(0,0)->(1,0)2s:(1,0)->(1,1)3s:(1,1)->(2,1)4s:(2,1)->
  • 标签:队列
http://acm.hdu.edu.cn/showproblem.php?pid=1026

题意:问从图的左上角到达右下角需要的最短时间,如果格子是数字n(1-9),说明有怪兽,要打死他花费n的时间

Sample Input


Sample Output
It takes 13 seconds to reach the target position, let me show you the way.
1s:(0,0)->(1,0)
2s:(1,0)->(1,1)
3s:(1,1)->(2,1)
4s:(2,1)->(2,2)
5s:(2,2)->(2,3)
6s:(2,3)->(1,3)
7s:(1,3)->(1,4)
8s:FIGHT AT (1,4)
9s:FIGHT AT (1,4)
10s:(1,4)->(1,5)
11s:(1,5)->(2,5)
12s:(2,5)->(3,5)
13s:(3,5)->(4,5)
FINISH
It takes 14 seconds to reach the target position, let me show you the way.
1s:(0,0)->(1,0)
2s:(1,0)->(1,1)
3s:(1,1)->(2,1)
4s:(2,1)->(2,2)
5s:(2,2)->(2,3)
6s:(2,3)->(1,3)
7s:(1,3)->(1,4)
8s:FIGHT AT (1,4)
9s:FIGHT AT (1,4)
10s:(1,4)->(1,5)
11s:(1,5)->(2,5)
12s:(2,5)->(3,5)
13s:(3,5)->(4,5)
14s:FIGHT AT (4,5)
FINISH
God please help our poor hero.
FINISH

#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <set>
//#include <map>
#include <queue>
#include <utility>
#include <iomanip>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
//#include <ctime>
#include <ctype.h>
using namespace std;
#define LL __int64
#define inf 0x3fffffff
#define M 105

struct point{
	int x;
	int y;
	int times;
	friend bool operator < (point a, point b)
	{
		return a.times > b.times;    //重载小于号使得小的先出队列
	}
};

struct Pre{
	int px, py;
}pre[M][M];

int r, c;
int x_move[4] = {-1, 0, 1, 0};
int y_move[4] = {0, 1, 0, -1};
char map[M][M];
bool vis[M][M];

void bfs (int x, int y)
{
	int i, v;
	vis[x][y] = true;
	point ft, tp;
	pre[x][y].px = -1;    //终点标记
	ft.x = x, ft.y = y, ft.times = 0;
	if (map[x][y] != '.')
		ft.times = map[x][y] - '0';
	priority_queue<point> q;    //优先队列
	q.push (ft);
	while (!q.empty())
	{
		ft = q.top();
		q.pop();
		if (ft.x == 0 && ft.y == 0)
		{
			printf ("It takes %d seconds to reach the target position, let me show you the way.\n", ft.times);
			int key = 1, total = ft.times;
			x = ft.x, y = ft.y;
			while (pre[x][y].px != -1)    //不断寻找前驱直到到达终点
			{
				int tx = pre[x][y].px;
				int ty = pre[x][y].py;
				printf ("%ds:(%d,%d)->(%d,%d)\n", key++, x, y, tx, ty);
				if (map[tx][ty] != '.')
					for (i = 0; i < map[tx][ty] - '0'; i++)
						printf ("%ds:FIGHT AT (%d,%d)\n", key++, tx, ty);
				x = tx;
				y = ty;
			}
			return ;
		}
		for (i = 0; i < 4; i++)
		{
			tp.x = ft.x + x_move[i];
			if (tp.x < 0 || tp.x >= r)
				continue;
			tp.y = ft.y + y_move[i];
			if (tp.y < 0 || tp.y >= c)
				continue;
			if (vis[tp.x][tp.y])
				continue;
			vis[tp.x][tp.y] = true;
			if (map[tp.x][tp.y] == 'X')
				continue;
			if (map[tp.x][tp.y] == '.')
				v = 1;
			else v = map[tp.x][tp.y] - '0' + 1;
			tp.times = ft.times + v;
		/**********记录tp的前驱ft**********/
			pre[tp.x][tp.y].px = ft.x;
			pre[tp.x][tp.y].py = ft.y;
		/**********记录tp的前驱ft**********/
			q.push (tp);
		}
	}
	puts ("God please help our poor hero.");
}

int main()
{
	int i;
	while (~scanf ("%d%d", &r, &c))
	{
		for (i = 0; i < r; i++)
			scanf ("%s", map[i]);
		memset (vis, false, sizeof(vis));
		bfs (r-1, c-1);    //倒过来搜索就可以不用栈了
		puts ("FINISH");
	}
	return 0;
}
  • 大小: 3.4 KB
  • 查看图片附件
发表评论
用户名: 匿名