HDU-1026,Ignatius and the Princess I(BFS+打印路径)

简介: HDU-1026,Ignatius and the Princess I(BFS+打印路径)

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.


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


题目大意:


1.Ignatius只能在四个方向(上,下,左,右)上移动,每秒只能移动一个步骤。步骤定义如下:如果当前位置是(x,y),则在步骤之后,Ignatius只能站立在(x-1,y),(x + 1,y),(x,y-1)或(x,y + 1)。

2.阵列上标有一些字符和数字。我们这样定义它们:

。 :Ignatius可以行走的地方。

X:这个地方是一个陷阱,伊格内修斯不应该在上面走。

n:这是一个拥有n HP(1 <= n <= 9)的怪物,如果伊格纳修斯在上面行走,他需要n秒才能杀死该怪物。


您的任务是给出一条路径,该路径花费了伊格内修斯到达目标位置的最短时间。您可以假设起始位置和目标位置永远不会是陷阱,并且起始位置也永远不会有怪物。

输入包含几个测试用例。每个测试用例都以一行开头,其中包含两个数字N和M(2 <= N <= 100,2 <= M <= 100),它们表示迷宫的大小。然后是一个N * M二维数组,它描述了整个迷宫。输入在文件末尾终止。样本输入中有更多详细信息。


对于每个测试用例,您应该输出“上帝,请帮助我们可怜的英雄”。如果Ignatius无法到达目标位置,或者您应该输出“到达目标位置需要n秒,请让我向您展示。”(n是最短的秒数),并告诉我们的英雄整个路径。在每个测试用例之后,输出包含“ FINISH”的行。如果路径不止一个,则此问题中任何一个都可以。示例输出中有更多详细信息。


程序代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
  int x,y,step;
  friend bool operator<(node n1,node n2)//看一下样例输出,我们可以考虑用优先级队列 
  {
    return n2.step<n1.step;
  }
};
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//方向数组 
int map[101][101];//地图 
int flag[101][101];//标记方向 
int blood[101][101];//某些格子的(怪物)血量 
int n,m,temp;
int judge(int x,int y)
{
  if(x>=0&&x<n&&y>=0&&y<m&&map[x][y]!=-1)//没有越界并且这个点不是障碍 
    return 1;
  return 0;
}
int bfs()
{
  priority_queue<node> q;//定义优先级队列 
  node head,tail;
  head.x=0;//坐标和步数初始均为0 
  head.y=0;
  head.step=0;
  map[0][0]=-1;//标记这个点 
  q.push(head);//入队 
  while(!q.empty())//队列不为空 
  {
    head=q.top();//取队首 
    q.pop();//弹出队首 
    if(head.x==n-1&&head.y==m-1)//到达目标位置 
      return head.step;
    for(int i=0;i<4;i++)
    {
      tail.x=head.x+dir[i][0];//移动之后的坐标 
      tail.y=head.y+dir[i][1];
      if(!judge(tail.x,tail.y))//如果这个点越界或者是障碍 
        continue;
      tail.step=head.step+1+map[tail.x][tail.y];//新的步数等于之前步数加1,再加上这个格子需要(有或者没有怪物)的时间 
      map[tail.x][tail.y]=-1;//标记这个点 
      flag[tail.x][tail.y]=i+1;//记录下一步的方向 
      q.push(tail);//新的结点入队 
    }
  }
  return -1;//无法到达则返回-1 
}
void find(int x,int y)//关键:打印路径!!! 
{
  if(!flag[x][y])//方向值错误 
    return ;
  int nx=x-dir[flag[x][y]-1][0];//回溯到上一步的方向所对应的坐标 
  int ny=y-dir[flag[x][y]-1][1];
  find(nx,ny);//递归每一步 
  printf("%ds:(%d,%d)->(%d,%d)\n",temp++,nx,ny,x,y);//秒数依次加1,从上一步的(nx,ny)到这一步的(x,y) 
  while(blood[x][y]--)//kill这个怪物所需要的时间以及坐标 
    printf("%ds:FIGHT AT (%d,%d)\n",temp++,x,y);
}
int main()
{
  char str[101];
  int ans;
  while(scanf("%d %d",&n,&m)!=EOF)
  {
    memset(map,0,sizeof(map));
    memset(flag,0,sizeof(flag));
    memset(blood,0,sizeof(blood));
    for(int i=0;i<n;i++)
    {
      scanf("%s",str);//用字符串将其读入 
      for(int j=0;j<m;j++)
      {
        if(str[j]=='.')
          map[i][j]=0;//可以经过的地方标记为0 
        else if(str[j]=='X')
          map[i][j]=-1;//障碍标记为-1 
        else
          map[i][j]=blood[i][j]=str[j]-'0';//代表格子上怪物的血量,经过此处需要的时间 
      }
    }
    ans=bfs();
    if(ans==-1)//无法到达目标位置 
      printf("God please help our poor hero.\n");
    else//可以到达 
    {
      printf("It takes %d seconds to reach the target position, let me show you the way.\n",ans);
      temp=1;
      find(n-1,m-1);
    }
    printf("FINISH\n");
  }
  return 0;
}


相关文章
POJ-2488,A Knight's Journey(DFS)
POJ-2488,A Knight's Journey(DFS)
HDU-1027,Ignatius and the Princess II
HDU-1027,Ignatius and the Princess II
|
算法 Go
HDU-1548,A strange lift(Dijkstra)
HDU-1548,A strange lift(Dijkstra)
hdu-1098 Ignatius's puzzle(费马小定理)
hdu-1098 Ignatius's puzzle(费马小定理)
125 0
hdu-1098 Ignatius's puzzle(费马小定理)
HDOJ/HDU 1372 Knight Moves(经典BFS)
HDOJ/HDU 1372 Knight Moves(经典BFS)
94 0
HDOJ/HDU 1241 Oil Deposits(经典DFS)
HDOJ/HDU 1241 Oil Deposits(经典DFS)
65 0
|
Java C语言
HDOJ/HDU 1029 Ignatius and the Princess IV(简单DP,排序)
HDOJ/HDU 1029 Ignatius and the Princess IV(简单DP,排序)
118 0
|
人工智能
HDOJ 1028 Ignatius and the Princess III(递推)
HDOJ 1028 Ignatius and the Princess III(递推)
98 0