HDU 1026(優先佇列+BFS+前驅記錄)

_Phoenix發表於2015-08-22

這道題是在晚上睡不著的時候做的。。。然後,就早上辣 (太弱啦~~(>_<)~~

這道題用普通的佇列存是不行的,因為存在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。。。。。



相關文章