hdu 1026 Ignatius and the Princess I

来源:互联网 发布:国民党正面战场 知乎 编辑:程序博客网 时间:2024/04/29 07:46

 

Ignatius and the Princess I

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2126    Accepted Submission(s): 617
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.
 

 

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.XXXXX15 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)FINISHIt 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)FINISHGod please help our poor hero.FINISH
 

 

Author
Ignatius.L
终于A掉了!!!!!!!!敲了半个下午的代码,吃晚饭都在想哪里错了。下午提交4次都是MLE,这个是多么郁闷的事啊!晚上本来不想管它了,谁知道我随便跟祝牛一说,他就注意了,我就趁他还爱学习的份上让他帮我看看。。。一开始,他提出什么DFS啊,DP啊之类的。不知道他真动过脑子没有啊。。如果他能用以上两种方法做出来,我绝对膜拜他!!!
好了 废话不多说,题目意思很简单,从(0,0)走到(n-1,m-1) 的最短路程,不过中间有敌人的,敌人的HP就是你要花多少时间干他!而且最后要输出你的行径路线。有多种符合的话任意一种都OK的!  前几天做了一套搜索的题目,bfs居多。。这次我也没多想,直接奔着BFS去了。。写了一半就卡。主要是思路不明确就下去了。路径怎么保存啊是半路杀出的猛虎。。我本来打算是输路径再来一次dFS,在第一次BFS中把每个点的最短步数保存,然后输路径的时候从          后面的步数 - 1 =(前一步+敌人HP)一直到到起点为止,然后返回true,然后一连串的输出来!!!好像方法是可以的!但很郁闷的是在第一次的BFS中出现致命错误!!因为这个题不代表走过之后就不再走,有的点还是需要再次去更新的!那种记忆BFS是行不通了。我也不管了,就写了个约束    首先把每个点的步数设为无穷大,然后要是上一步的花费(上一个点的步数加上它的HP)+1 < 当前点的步数!我就让它进来,并加入到队列!问题来了,有可能队中同时存在了同个点!但是能再次加到队列中肯定是最新的!但问题是前面那个点是旧的了。旧归旧也好,但它出队还要去干坏事(指去更新其他点,然后不断有点加到队列中,虽然队列中的最新点能弥补它的错误,但队列越来越长,以至于导致了我的悲剧!!!!!!!(是祝牛再去SHOPPING的时候短信捎来的,大牛,感谢!!)
                  华丽的MLE!!!!!!!
好了上面那些也不是白讲的,MLE嘛,无非就是队列中的旧点干的坏事嘛,别让它干不就OK了!!在加个数组判断下队列中是否有旧点就行!
还有那个路径输出,DFS是不错的,还可以温故呢,,,但这纯粹是练习的需要。。不需要的可以之间再来个数组,边BFS边记录上一个点!
然后在输出就行了!!             = .=!
成果码!!仅供参照!

include<iostream>
include<queue>
using namespace std;
const int INF = 10000;
struct fuck
{
 int i,j,hp,step;
 char ch;
}map[102][102];

struct Way
{
 int x,y;
}w[102][102];

int flag;
int c;
int n,m;
int mark[102][102];

int dir[4][2] = {1,0,-1,0,0,1,0,-1};

int judge(int a,int b)
{
 if(a>=0&&a<n&&b>=0&&b<m)
  return 1;
 return 0;
}

void bfs()
{
 queue<fuck> Q;
 fuck t;
 map[0][0].step = 0;
 Q.push(map[0][0]);
 mark[0][0] = 1;
 int i,q,p;
 while(!Q.empty())
 {
  t = Q.front();
  Q.pop();
  while(mark[t.i][t.j] > 1)
  {
   mark[t.i][t.j] --;
   t = Q.front();
    Q.pop();
  }
  mark[t.i][t.j] = 0; 
  for(i=0;i<4;i++)
  {
   q = t.i + dir[i][0];
   p = t.j + dir[i][1];
   if(judge(q,p) && map[q][p].ch != 'X' && t.step+t.hp + 1 < map[q][p].hp + map[q][p].step )
   {
    w[q][p].x = t.i;
    w[q][p].y = t.j;
    map[q][p].step = t.step+t.hp + 1;
     Q.push(map[q][p]);
     mark[q][p] ++;
   }
  }
 }
 if(map[n-1][m-1].step != INF)
  flag = 0;
}

void show_way(int a,int b)
{
 if(w[a][b].x == a && w[a][b].y==b)
 {
  while(map[a][b].hp--)
   printf("%ds:FIGHT AT (%d,%d)/n",c ++,a,b);
  return ;
 }
 show_way(w[a][b].x,w[a][b].y);
 printf("%ds:(%d,%d)->(%d,%d)/n",c++,w[a][b].x,w[a][b].y,a,b);
 while(map[a][b].hp--)
   printf("%ds:FIGHT AT (%d,%d)/n",c ++,a,b);
 
}


int main()
{
 int i,j;
 while(cin>>n>>m)
 {
  for(i=0;i<n;i++)
  {
   getchar();
   for(j=0;j<m;j++)
   {
    scanf("%c",&map[i][j].ch);
    map[i][j].step = INF;
    if(map[i][j].ch>'0' &&map[i][j].ch <='9')
     map[i][j].hp = map[i][j].ch - '0';
    else
     map[i][j].hp = 0;
    map[i][j].i = i;
    map[i][j].j = j;
    w[i][j].x = i;
    w[i][j].y = j;
    mark[i][j] = 0;
   }
  }
  flag = 1;
  bfs();
  if( flag)
   cout<<"God please help our poor hero./nFINISH/n";
  else
  {
   printf("It takes %d seconds to reach the target position, let me show you the way./n",map[n-1][m-1].hp + map[n-1][m-1].step);
   c = 1;
   show_way(n-1,m-1);
   cout<<"FINISH/n";
  }
 } 
 return 0;
}

原创粉丝点击