HDU 1026 Ignatius and the Princess I
就是简单的广搜走迷宫找最短路径,不过每次路径不单单是走的距离,还有格子上杀怪的时间,所以可以利用优先队列,按到达某个节点已经消耗的时间排序,逐个取出来广搜。
另外题目还要求最后输出最短路径,可以用一个和迷宫一样的数组,保存每个点上一步的节点,这样BFS结束后,从终点往前找,并压入栈中,一直到起点位置。然后按时间序列输出,当时间小于该点应消耗的时间时,说明在这点上打怪了,按题目输出即可。
其实现在感觉这题写的有点杂乱。。。不过好歹是自己难得一次过的BFS。。。
AC代码:
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#include<stack>
using namespace std;
int n, m;
char matrix[105][105];
bool vis[105][105] = {false};
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
struct Node{
int x, y;
int steps;
Node(){}
Node(int x, int y, int steps){
this->x = x;
this->y = y;
this->steps = steps;
}
bool operator<(const Node& o) const{
return this->steps >= o.steps;
}
void show(){
cout << "(" << x << "," << y << ")";
}
};
void bfs();
void showPath(int s);
bool isLegal(int x, int y);
Node dp[105][105];
int main(void)
{
freopen("in.txt", "r", stdin);
while(cin >> n >> m)
{
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
cin >> matrix[i][j];
memset(vis, 0, sizeof(vis));
memset(dp, 0, sizeof(dp));
bfs();
cout << "FINISH" << endl;
}
return 0;
}
void bfs()
{
priority_queue<Node> q;
q.push(Node(0, 0, 0));
vis[0][0] = true;
while(!q.empty())
{
Node node = q.top();
q.pop();
if(node.x == n-1 && node.y == m-1){ //Find the target
cout << "It takes " << node.steps << " seconds to reach the target position, let me show you the way." << endl;
showPath(node.steps);
return;
}
for(int i = 0; i < 4; i++) //BFS for up & down & left & right, to find Reachable Point
{
int xx = node.x + dx[i];
int yy = node.y + dy[i];
if(isLegal(xx, yy)) //judge if the point is legal
{
vis[xx][yy] = true;
int newStep = node.steps + 1;
if(matrix[xx][yy] != '.') //account for the time fighting monster
newStep += matrix[xx][yy] - 48;
Node newNode(xx, yy, newStep);
dp[xx][yy] = node;
q.push(newNode);
}
}
}
cout << "God please help our poor hero." << endl;
return;
}
void showPath(int s)
{
int x = n-1;
int y = m-1;
Node curNode(x, y, s); //end point
stack<Node> stack;
while(x != 0 || y != 0)
{
stack.push(curNode); //push into stack reversely
curNode.x = dp[x][y].x;
curNode.y = dp[x][y].y;
curNode.steps = dp[x][y].steps;
x = curNode.x;
y = curNode.y;
}
stack.push(Node(0, 0, 0));
curNode = stack.top();
stack.pop();
for(int i = 1; i <=s; i++)
{
cout << i << "s:";
curNode.show();
cout << "->";
curNode = stack.top();
stack.pop();
curNode.show();
cout << endl;
for(int j = i + 1; j <= curNode.steps; j++) //Fighting monster
{
cout << j << "s:";
cout << "FIGHT AT ";
curNode.show();
cout << endl;
i = j;
}
}
}
bool isLegal(int x, int y)
{
if(x < 0 || y < 0 || x >= n || y >= m || vis[x][y] || matrix[x][y] == 'X')
return false;
return true;
}