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. perl 访问网站一些useragent的设置

    121.40.205.143 - - [22/Jun/2016:12:56:23 +0800] "GET /wechat/account.html HTTP/1.1" 200 34 ...

  2. Config File Settings Of EF——实体框架的配置文件设置

    我亦MSDN 原文地址 http://msdn.microsoft.com/en-us/data/jj556606 Entity Framework allows a number of settin ...

  3. 无状态TCP的ip_conntrack

    Linux的ip_conntrack实现得过于沉重和精细.而实际上有时候,根本不需要在conntrack中对TCP的状态进行跟踪,只把它当UDP好了,我们的需求就是让系统可以将一个数据包和一个五元组标 ...

  4. VSTO之旅系列(二):创建Excel解决方案

    原文:VSTO之旅系列(二):创建Excel解决方案 本专题概要 引言 创建VSTO项目 Excel对象模型 创建Excel外接程序 创建Excel文档级自定义项 小结 一.引言 也许很多朋友都没有听 ...

  5. Delphi 基本数据类型列表 高级数据类型列表 字符类型查询列表清单

    原文:Delphi 基本数据类型列表 高级数据类型列表 字符类型查询列表清单 长长的列表文字类型文件 分类 范围 字节 备注 简单类型 序数 整数 Integer -2147483648 .. 214 ...

  6. Selenium 验证picklist是可被正确选中且是有序的(动态数组赋值)

    原代码: <select id="edit-submitted-im-interesting-in" class="form-select required&quo ...

  7. Hlg 1832 【线段树 && RMQ】.cpp

    题意: 在给出的区间内求出最大买进卖出的差价. 思路: 对于弱数据:维护一个从左到右的最大差价和最小值.即当发现当前值比最小值小的时候更新最小值,否则看一下当前值与之前最小值的差价是否比最大差价大,是 ...

  8. crm操作安全字段

    using System;     using Microsoft.Xrm.Sdk;     using Microsoft.Xrm.Sdk.Messages; /// <summary> ...

  9. Android -&gt; 怎样避免Handler引起内存泄露

    很多其它内容,可訪问个人博客www.liangfeizc.com 错误代码 假设在Activiy中通过内部类(Runnable)的方式定义了一个变量runnable, final Runnable r ...

  10. 使用注解实现 bean 转 csv

    csv 文件是 aaa,bbb,ccc aaa,bbb,ccc 保存 这里的要求是 List<T> 线性表的类型 转换成 类别似 html 中 table的格式,即第一行是 head 后面 ...