Ignatius and the Princess I
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 18585 Accepted Submission(s): 5986
Special Judge
Problem Description
The Princess has been abducted by the BEelzebub feng5166, our hero Ignatius has to rescue our pretty Princess. Now he gets into feng5166's castle. The castle is a large labyrinth. To make the problem simply, we assume the labyrinth is a N*M two-dimensional array which left-top corner is (0,0) and right-bottom corner is (N-1,M-1). Ignatius enters at (0,0), and the door to feng5166's room is at (N-1,M-1), that is our target. There are some monsters in the castle, if Ignatius meet them, he has to kill them. Here is some rules:
1.Ignatius can only move in four directions(up, down, left, right), one step per second. A step is defined as follow: if current position is (x,y), after a step, Ignatius can only stand on (x-1,y), (x+1,y), (x,y-1) or (x,y+1).
2.The array is marked with some characters and numbers. We define them like this:
. : The place where Ignatius can walk on.
X : The place is a trap, Ignatius should not walk on it.
n : Here is a monster with n HP(1<=n<=9), if Ignatius walk on it, it takes him n seconds to kill the monster.
Your task is to give out the path which costs minimum seconds for Ignatius to reach target position. You may assume that the start position and the target position will never be a trap, and there will never be a monster at the start position.
1.Ignatius can only move in four directions(up, down, left, right), one step per second. A step is defined as follow: if current position is (x,y), after a step, Ignatius can only stand on (x-1,y), (x+1,y), (x,y-1) or (x,y+1).
2.The array is marked with some characters and numbers. We define them like this:
. : The place where Ignatius can walk on.
X : The place is a trap, Ignatius should not walk on it.
n : Here is a monster with n HP(1<=n<=9), if Ignatius walk on it, it takes him n seconds to kill the monster.
Your task is to give out the path which costs minimum seconds for Ignatius to reach target position. You may assume that the start position and the target position will never be a trap, and there will never be a monster at the start position.
Input
The input contains several test cases. Each test case starts with a line contains two numbers N and M(2<=N<=100,2<=M<=100) which indicate the size of the labyrinth. Then a N*M two-dimensional array follows, which describe the whole labyrinth. The input is terminated by the end of file. More details in the Sample Input.
Output
For each test case, you should output "God please help our poor hero." if Ignatius can't reach the target position, or you should output "It takes n seconds to reach the target position, let me show you the way."(n is the minimum seconds), and tell our hero the whole path. Output a line contains "FINISH" after each test case. If there are more than one path, any one is OK in this problem. More details in the Sample Output.
Sample Input
5 6 .XX.1. ..X.2. 2...X. ...XX. XXXXX. 5 6 .XX.1. ..X.2. 2...X. ...XX. XXXXX1 5 6 .XX... ..XX1. 2...X. ...XX. XXXXX.
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
题解:简单的bfs题,只不过要用到优先队列,普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。
优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有1) 查找;2) 插入一个新元素;3) 删除.在最小优先队列(min priorityq u e u e)中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列(max priority queue),查找操作用来搜索优先权最大的元素,删除操作用来删除该元素.优先权队列中的元素可以有相同的优先权,查找与删除操作可根据任意优先权进行.
在使用优先队列 的时候,需要重载<运算符,如果重载,将会使用默认的优先级,头文件为queue,更多的关于优先队列请参考
http://www.cnblogs.com/heqinghui/archive/2013/07/30/3225407.html
本题还要注意路径问题,用flag数组来存储从父节点通过怎样的操作到达子节点(向上,下,左,右),递归输出就行,用blood数组存储怪物的血量,在输出路径的时候,需要用到,
代码:
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
#define Max 105
int dir[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};
int map[Max][Max], flag[Max][Max], blood[Max][Max];
int n, m, cnt;
struct node {
int x, y;
int step;
};
bool operator < (node a, node b) {
return a.step > b.step;
}
priority_queue<node>que;
int check(int a, int b) {
if(a < 0 || b < 0 || a >= n || b >= m)
return 1;
return 0;
}
int bfs() {
int i, next_x, next_y;
while(!que.empty())
que.pop();
node frist, next;
frist.step = 0;
frist.x = 0;
frist.y = 0;
map[0][0] = -1;
que.push(frist);
while(!que.empty()) {
frist = que.top();
que.pop();
if(frist.x == n - 1 && frist.y == m - 1)
return frist.step;
for(i = 0; i < 4; i++) {
next_x = frist.x + dir[i][0];
next_y = frist.y + dir[i][1];
if(check(next_x, next_y))
continue;
if(map[next_x][next_y] != -1) {
map[next_x][next_y] = -1;
next.x = next_x;
next.y = next_y;
next.step = frist.step + blood[next_x][next_y] + 1;
flag[next_x][next_y] = i + 1;
que.push(next);
}
}
}
return 0;
}
void outPut(int x, int y) {
if(!flag[x][y])
return;
else {
outPut(x - dir[flag[x][y]-1][0], y - dir[flag[x][y]-1][1]);
printf("%ds:(%d,%d)->(%d,%d)\n", cnt++, x - dir[flag[x][y]-1][0], y - dir[flag[x][y]-1][1], x, y);
while(blood[x][y]--) {
printf("%ds:FIGHT AT (%d,%d)\n", cnt++, x, y);
}
}
}
int main() {
int j, i;
while(scanf("%d%d", &n, &m) != EOF) {
memset(map, 0, sizeof(map));
memset(flag, 0, sizeof(flag));
memset(blood, 0, sizeof(blood));
char s[Max];
for(i = 0; i < n; i++) {
scanf("%s", s);
for(j = 0; s[j]; j++) {
if(s[j] == '.')
map[i][j] = 0;
else if(s[j] == 'X')
map[i][j] = -1;
else
map[i][j] = blood[i][j] = s[j] - '0';
}
}
int ans = 0;
ans = bfs();
if(ans) {
printf("It takes %d seconds to reach the target position, let me show you the way.\n", ans);
cnt = 1;
outPut(n - 1, m - 1);
}
else
printf("God please help our poor hero.\n");
printf("FINISH\n");
}
}