HDU 1026(优先队列+BFS+前驱记录)

这道题是在晚上睡不着的时候做的。。。然后,就早上辣 (太弱啦~~(>_<)~~

这道题用普通的队列存是不行的,因为存在monster,打怪兽需要时间,所以即使步数相同,打怪耗时也不同。假设存在两条都能到达目标的路,但是由于monster需要耗费时间,所以需要将队列中的成员按照耗时的大小进行从小到大的排序,这样,当到达终点时所选取的路径就是耗时最少的了。

所以,考虑使用可以对成员进行排序的优先队列来操作。。。这里涉及到一个运算符的重载问题,关于运算符重载的构造我写在了小贴士里边,蛮简单的。

贴上链接:优先队列中重载运算符>和<

另外,这道题需要记录路径,之前是想用栈来存数据的,然后发现如果倒着搜索的话就不用这么麻烦的一个个的弹栈辣,所以是从终点开始搜索的=。=然后开一个数组来记录每一个坐标的前驱,然后用循环迭代将每个对应的坐标进行输出。

另外还有一些小细节多WA几次就发现辣TAT

代码如下:

#include<iostream>
#include<queue>
#include<cstring>
#define M 105
using namespace std;
int n,m;
char map[M][M];
int vis[M][M];
struct node
{
	int x, y, step;
	friend bool operator < (node a, node b)
	{
		return a.step > b.step;
	}
};
struct pre
{
	int x, y;
};
pre pre[M][M];
int dr[4][2] = {{-1,0}, {1,0}, {0, -1}, {0, 1}};
void bfs(int end_x, int end_y)
{
	node end;
	end.x = end_x;
	end.y = end_y;
	vis[end_x][end_y] = 1;
	pre[end_x][end_y].x = 233333;
	pre[end_x][end_y].y = 233333;
	if (map[end_x][end_y] != '.')
		end.step = map[end_x][end_y] - '0';
	else
		end.step = 0;
	priority_queue<node> q;
	q.push(end);
	while (!q.empty())
	{
		node temp = q.top();
		q.pop();
		if (temp.x == 0 && temp.y == 0)
		{
			int count = 1;
			printf("It takes %d seconds to reach the target position, let me show you the way.\n",temp.step);
			while (temp.x != end_x || temp.y != end_y)
			{
				printf("%ds:(%d,%d)->(%d,%d)\n",count++, temp.x, temp.y, pre[temp.x][temp.y].x, pre[temp.x][temp.y].y);
				if (map[pre[temp.x][temp.y].x][pre[temp.x][temp.y].y] != '.')
				{
					int c = map[pre[temp.x][temp.y].x][pre[temp.x][temp.y].y] - '0';
					while (c--)
					{
						printf("%ds:FIGHT AT (%d,%d)\n", count++, pre[temp.x][temp.y].x, pre[temp.x][temp.y].y);
					}
				}
				int num = temp.x;
				temp.x = pre[temp.x][temp.y].x;
				temp.y = pre[num][temp.y].y;
			}
			return;
		}
		int x, y;
		for (int i=0; i<4; i++)
		{
			node save = temp;
			x = temp.x + dr[i][0];
			y = temp.y + dr[i][1];
			if (x>=0 && x<n && y>=0 && y<m)
			{
				if (!vis[x][y])
				{
					if (map[x][y] != 'X')
					{
						vis[x][y] = 1;
						pre[x][y].x = temp.x; 
						pre[x][y].y = temp.y;
						save.x = x;
						save.y = y;
						if (map[x][y] != '.')
							save.step = temp.step + map[x][y] - '0' + 1;
						else
							save.step = temp.step + 1;
						q.push(save);
					}
				}
			}
		}
	}
	printf("God please help our poor hero.\n");
}
int main()
{
	while (~scanf("%d %d",&n, &m))
	{
		memset(map,0,sizeof(map));
		memset(vis,0,sizeof(vis));
		for (int i=0; i<n; i++)
			cin >> map[i];
		bfs(n-1, m-1);
		printf("FINISH\n");
	}
	return 0;
}

自己真的是太弱辣,求各位巨巨的指点QAQ。。。。。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值