hdu-1242Rescue(优先队列+bfs)

Rescue

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 23586    Accepted Submission(s): 8336


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
 
 题意: 移动需要1单位时间,杀死一个看守也需要1单位时间。到达一个格子以后,如果该格子有看守,则一定要杀死。交给你的任务是,最少要多少单位时间,才能到达Angel所在的地方?“#”代表墙,“.”表示可以移动,“x”表示看守,“a”表示Angel,“r”表示救援队伍。(r可能有多个)
分析:因为r可能有多人,所以我们可以逆着走,由a----->r,用的队列,搜索到第一个r就能结束。关于discuss里说普通队列+bfs能ac,是数据太水。因为击败守卫需要消耗时间1,因此普通队列每一次出队列的元素只是步数上最优,但不一定是时间上最优的,这时即使我们把整个迷宫搜完以最小值作为最优依然不行,因为每一步处理完成都会把该状态标记为已处理vis[i][j]=1,因此,只要有一步不是最优,就会影响后面的结果。这题的正确做法是优先队列,每一次出队都是出时间最少的,这样可以保证每一步最优,并且一旦搜到目标即可立刻结束。
(后来我想了一下,用普通队列也并非不可以,要把vis数组特殊处理一下,留给你们一些想象的空间,我就不说了)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#define INF 0x3f3f3f3f
#define Pn printf("\n")
#define CSH(a, b) memset(a, (b), sizeof(a))
#define LL long long
#define PRnode(q) priority_queue<node> q
using namespace std;
char map[202][202];
int dir[4][2]={1,0,  0,1   ,-1,0   ,0,-1};
struct node
{
    int x,y,num;
    bool operator < (const node &a) const
    {
        return num>a.num;//小值优先
    }
    
}first,ne;
int n,m;
int bfs()
{
    PRnode(q);
    q.push(first);
    while(!q.empty())
    {
        first=q.top();
        q.pop();
        for(int i=0;i<4;i++)
        {
            ne.x=first.x+dir[i][0];
            ne.y=first.y+dir[i][1];
            if(ne.x>=0&&ne.x<n&&ne.y>=0&&ne.y<m&&map[ne.x][ne.y]!='#')
            {
                if(map[ne.x][ne.y]=='r')
                {
                    ne.num=first.num+1;
                    return ne.num;
                }
                else if(map[ne.x][ne.y]=='x')
                {
                    ne.num=first.num+2;
                }
                else if(map[ne.x][ne.y]=='.')
                {
                    ne.num=first.num+1;
                }
                map[ne.x][ne.y]='#';
                q.push(ne);
            }
        }
    }
    return INF;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<n;i++)
        {
            getchar();
            for(int j=0;j<m;j++)
            {
                scanf("%c",&map[i][j]);
                if(map[i][j]=='a')
                {
                    first.x=i;
                    first.y=j;
                    first.num=0;
                    map[i][j]='#';
                }
            }
        }
        int out=bfs();
        out!=INF?printf("%d\n",ne.num):printf("Poor ANGEL has to stay in the prison all his life.\n");
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值