HDU 1242 Rescue (bfs + priority_queue)

    本来一直不想写题解的,因为网上有一大堆的题解,可能有更好的解法,但是最近在看之前做过的题目时,发现很难找到,然后准备开始把一些有收获的题目记一下,哪怕是一点点的收获也好、、

   

Rescue


Problem Description

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
 
    一开始看到这题的时候,我以为只是普通的bfs,兴冲冲地敲完,以为可以1A ,结果错了,bug 也找不出来。
    看了discuss,可能是因为数据比较弱,有种dir可以直接过的,但是其他的就不行了,这里就需要用到优先队列了,因为是否要经过狱长会影响时间(题目中的符号为“x”),
另外一点需要注意的是,题目中的r 可能存在多个,所以我们可以从a 开始搜。
    优先队列的时候,注意重载<。

    优先队列版、
   
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

char mpt[210][210];
bool vis[210][210];
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int n, m;

struct node
{
    int x, y;
    int step;
    bool operator <(const node &t) const  // 重载 <
    {
        return t.step < step;
    }
};

node sta;

void bfs()
{
    memset(vis, false, sizeof(vis));
    priority_queue<node> qe;
    while(!qe.empty())
    {
        qe.pop();
    }

    node tmp, next;

    qe.push(sta);
    vis[sta.x][sta.y] = true;
    while(!qe.empty())
    {
        tmp = qe.top(); // 注意这里是top(),而普通队列中是front()
        qe.pop();
        for(int i = 0; i < 4; i ++)
        {
            next.x = tmp.x + dir[i][0];
            next.y = tmp.y + dir[i][1];
            next.step = tmp.step + 1;
            if(mpt[next.x][next.y] == 'r')
            {
                printf("%d\n",next.step);
                return;
            }
            if(next.x > 0 && next.y > 0 && next.x < n && next.y < m && mpt[next.x][next.y] != '#' &&!vis[next.x][next.y])
            {
                if(mpt[next.x][next.y] == 'x')
                {
                    next.step ++;
                }
                vis[next.x][next.y] = true;
                qe.push(next);
            }
        }
    }
    printf("Poor ANGEL has to stay in the prison all his life.\n");
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i = 0; i < n; i ++)
        {
            scanf("%s",mpt[i]);
        }
        for(int i = 0; i < n; i ++)
        {
            for(int j = 0; j < m; j ++)
            {
                if(mpt[i][j] == 'a')
                {
                    sta.x = i;
                    sta.y = j;
                    sta.step = 0;
                    break;
                }
            }
        }
        bfs();
    }
}

    水过的普通bfs,据说是因为数据太弱,然后过的。。
   
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

char mpt[210][210];
bool vis[210][210];
int dir[4][2] = {1,0,0,1,-1,0,0,-1}; // discuss 里面说这个dir 的定义可以过,果然、、、
int n, m;

struct node
{
    int x, y;
    int step;
};

node sta;

void bfs()
{
    memset(vis, false, sizeof(vis));
    queue<node> qe;
    while(!qe.empty())
    {
        qe.pop();
    }

    node tmp, next;

    qe.push(sta);

    while(!qe.empty())
    {
        tmp = qe.front();
        qe.pop();
        for(int i = 0; i < 4; i ++)
        {
            next.x = tmp.x + dir[i][0];
            next.y = tmp.y + dir[i][1];
            next.step = tmp.step + 1;
            if(mpt[next.x][next.y] == 'r')
            {
                printf("%d\n",next.step);
                return;
            }
            if(next.x > 0 && next.y > 0 && next.x < n && next.y < m && mpt[next.x][next.y] != '#' &&!vis[next.x][next.y])
            {
                if(mpt[next.x][next.y] == 'x')
                {
                    next.step ++;
                }
                vis[next.x][next.y] = true;
                qe.push(next);
            }
        }
    }
    printf("Poor ANGEL has to stay in the prison all his life.\n");
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i = 0; i < n; i ++)
        {
            scanf("%s",mpt[i]);
        }
        for(int i = 0; i < n; i ++)
        {
            for(int j = 0; j < m; j ++)
            {
                if(mpt[i][j] == 'a')
                {
                    sta.x = i;
                    sta.y = j;
                    sta.step = 0;
                    break;
                }
            }
        }
        bfs();
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值