Rescue

Time Limit: 2 Seconds      Memory Limit: 65536 KB

Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison.

Angel's friends want to save Angel. Their task is: approach Angel. We assume that "approach Angel" is to get to the position where Angel stays. When there's a guard in the grid, we must kill him (or her?) to move into the grid. We assume that we moving up, down, right, left takes us 1 unit time, and killing a guard takes 1 unit time, too. And we are strong enough to kill all the guards.

You have to calculate the minimal time to approach Angel. (We can move only UP, DOWN, LEFT and RIGHT, to the neighbor grid within bound, of course.)

Input

First line contains two integers stand for N and M.

Then N lines follows, every line has M characters. "." stands for road, "a" stands for Angel, and "r" stands for each of Angel's friend.

Process to the end of the file.

Output

For each test case, your program should output a single integer, standing for the minimal time needed. If such a number does no exist, you should output a line containing "Poor ANGEL has to stay in the prison all his life."

Sample Input

7 8 
#.#####. 
#.a#..r. 
#..#x... 
..#..#.# 
#...##.. 
.#...... 
........

Sample Output

13

如题。简单的广搜水题,问题在于如何扩展x的结点。方法也很简单。可以把x看做一个有两个结点的连通分量,第一次进入x结点时,只能扩展出一个结点(还是x自己),第二次进入x结点时,才能扩展出周围四个方向的结点。

当然,为了避免出现死循环,必须要把x结点的值更改。我是更改为'.'。

最后的最小值,则是广搜树的高度。

下面是AC代码

#include <stdio.h>
#include <queue>
using namespace std;
/*
整整两个小时的时间!!!!
居然是忘记清空队列的低级BUG!!!!

1、标记是否访问过某个结点,如果访问过,则不再入队;
2、如果当前的结点值是x,则需要将这个访问过的结点再次入队,并更改为.,本轮不再扩展。类似于将该点展开为一个线段,头扩展的结点是尾,尾扩展周围的结点。

*/
typedef struct point
{
       int x;
       int y;
}point;

queue<point> road;
char prison[201][201];
int visit[201][201];
int high[201][201];
int n,m;
int startX,startY;

void init()
{
      for(int i = 0;i < n;i++)
     {
            for(int j = 0;j < m;j++)
           {
                     if(prison[i][j] == 'a')
                    {
                         startX = i;
                         startY = j;
                    }
           }
      }
      for(int i = 0;i < 201;i++)
               for(int j = 0;j < 201;j++)
               {
                         high[i][j] = 0;
                         visit[i][j] = 0;
               }
       while(!road.empty())
                 road.pop();    //f*cking bug occurs here.
}

void BFS()
{
       point tmp;
       point p1;
       tmp.x = startX;
       tmp.y = startY;
       int finalX,finalY;
       high[startX][startY] = 0;
       visit[startX][startY] = 1;
       road.push(tmp);
       int flag = 0;
       while(!road.empty())
      {
               tmp = road.front();
               road.pop();
               if(prison[tmp.x][tmp.y] == 'x')
               {
                     road.push(tmp);
                     high[tmp.x][tmp.y] ++;
                     prison[tmp.x][tmp.y] = '.';
               }
              else if(prison[tmp.x][tmp.y] == 'r')
              {
                     flag = 1;
                     finalX = tmp.x;
                     finalY = tmp.y;
                     break;
              }
              else
             {
                     for(int i = -1;i <= 1;i++)
                     {
                              if(0 == i)continue;
                              if(tmp.x + i >= 0 && tmp.x + i < n)
                             {
                                        if(visit[tmp.x+i][tmp.y] == 0 && prison[tmp.x+i][tmp.y] != '#')
                                        {
                                                visit[tmp.x+i][tmp.y] = 1;
                                                p1.x = tmp.x + i;
                                                p1.y = tmp.y;
                                                high[p1.x][p1.y] = high[tmp.x][tmp.y] + 1;
                                                road.push(p1);
                                        }
                              }
                             if(tmp.y + i >= 0 && tmp.y + i < m)
                            {
                                       if(visit[tmp.x][tmp.y+i] == 0 && prison[tmp.x][tmp.y+i] != '#')
                                      {
                                                visit[tmp.x][tmp.y+i] = 1;
                                                p1.x = tmp.x;
                                                p1.y = tmp.y + i;
                                                high[p1.x][p1.y] = high[tmp.x][tmp.y] + 1;
                                                road.push(p1);
                                       }
                            }
                      }
                }
        }
        if(flag)
       {
             printf("%d\n",high[finalX][finalY]);
       }
       else printf("Poor ANGEL has to stay in the prison all his life.\n");
}

int main(void)
{
        while(scanf("%d%d",&n,&m) != EOF)
       {
               for(int i = 0;i < n;i++)
               scanf("%s",prison[i]);
               init();
               BFS();
       }
       return 0;
}

【原创】ZOJ_1649 Rescue 解题报告的更多相关文章

  1. 【原创】leetCodeOj --- Sliding Window Maximum 解题报告

    天,这题我已经没有底气高呼“水”了... 题目的地址: https://leetcode.com/problems/sliding-window-maximum/ 题目内容: Given an arr ...

  2. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  3. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  4. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  5. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  6. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  7. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

  8. 习题:codevs 1519 过路费 解题报告

    今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...

  9. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

随机推荐

  1. 玩转Windows服务系列——Windows服务小技巧

    原文:玩转Windows服务系列——Windows服务小技巧 伴随着研究Windows服务,逐渐掌握了一些小技巧,现在与大家分享一下. 将Windows服务转变为控制台程序 由于默认的Windows服 ...

  2. java学习笔记05--字符串 .

    java学习笔记05--字符串 . 一.String类 由字符所组成的一串文字符号被称之为字符串.在java中字符串不仅仅是字符数组,而且是String类的一个实例,可以使用String类来构建. 字 ...

  3. 图像编程学习笔记1——bmp文件结构处理与显示

    文本内容转载自<数字图像处理编程入门>,代码为自己实现 1.1图和调色板的概念 如今Windows(3.x以及95,98,NT)系列已经成为绝大多数用户使用的操作系统,它比DOS成功的一个 ...

  4. LCA 最近公共祖先 tarjan离线 总结 结合3个例题

    在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...

  5. SQL SERVER CHARINDEX函数

    CHARINDEX函数经常常使用来在一段字符中搜索字符或者字符串.假设被搜索的字符中包括有要搜索的字符,那么这个函数返回一个非零的整数,这个整数是要搜索的字符在被搜索的字符中的開始位数.即CHARIN ...

  6. 优酷m3u8视频源地址获取失败

    昨天和今天上午,优酷站点视频全然没有办法播放,可是我是获取的优酷视频的视频原地址,所以app还是能够正常播放而且有下载功能.今天下午開始,优酷视频网页能够訪问了,可是视频原地址却不在了.我全部的app ...

  7. SPOJ DISUBSTR(后缀数组)

    传送门:DISUBSTR 题意:给定一个字符串,求不相同的子串. 分析:对于每个sa[i]贡献n-a[i]个后缀,然后减去a[i]与a[i-1]的公共前缀height[i],则每个a[i]贡献n-sa ...

  8. VSTO 学习笔记(十三)谈谈VSTO项目的部署

    原文:VSTO 学习笔记(十三)谈谈VSTO项目的部署 一般客户计算机专业水平不高,但是有一些Office水平相当了得,尤其对Excel的操作非常熟练.因此如果能将产品的一些功能集成在Office中, ...

  9. OC-Protocol实现业务代理

    创建一个Protocol,相当于java的接口,但,有些方法不必实现,例如以下 #import <Foundation/Foundation.h> @protocol MyProtocol ...

  10. Android开源项目pulltorefresh分析与简单使用

    在Android开发中有时我们须要訪问网络实时刷新数据.比方QQ好友在线状态最新信息,QQ空间须要显示很多其它的好友动态信息,EOE论坛client显示很多其它的文章帖子信息等.android-pul ...