BFS:HDU-1242-Rescue(带守卫的迷宫问题)(优先队列)

解题心得:

1.读清楚题意,本题的题意是有多个‘r’(起点),多个r多个bfs比较最短的时间即可,但是hdoj的数据比较水,直接一个起点就行了,迷宫里有多个守卫,如果在路途中遇到守卫会多花费一个时间点,求最短时间救到公主。

2.(解法一)因为遇到守卫会多花费一个时间,所以在守卫的地方再次压入,但是时间加一,这样就可以让队列里面的先验证。

3.之前将此题理解为要将所有的守卫打败之后,才能救到天使,之前题意理解错误用了回溯法,找出所有打败全部守卫的情况,找到最短的路径。此题的数据0<n<m<=200,很明显的会超时。

4.(解法二)使用优先队列,虽然看起来和解法一相差不大,但是如果打败守卫的时间不同那么解法二将明显更方便。


题目:


Rescue
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 29754    Accepted Submission(s): 10489


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
 

Author
CHEN, Xue



解法一代码:
#include<stdio.h>
#include<queue>
#include<cstring>
using namespace std;
struct node
{
    int x,y,step;
}now,Next;
char maps[210][210];
int use[210][210],n,m;
int dir[4][2]={1,0,-1,0,0,1,0,-1};

bool check(int x,int y)
{
    if(x<0 || y<0 || x>=n || y>=m || use[x][y] || maps[x][y] == '#')
        return false;
    else
        return true;
}
void maps_store()
{

    for(int i=0;i<n;i++)
    {
        scanf("%s",maps[i]);
        for(int j=0;j<m;j++)
        {
            if(maps[i][j] == 'r')
            {
                now.x = i;
                now.y = j;
                now.step = 0;
            }
        }
    }
}

void bfs()
{
    queue <node> qu;
    qu.push(now);
    use[now.x][now.y] = 1;
    while(!qu.empty())
    {
        now = qu.front();
        qu.pop();
        if(maps[now.x][now.y] == 'a')
        {
            printf("%d
",now.step);
            return ;
        }
        if(maps[now.x][now.y] == 'x')
        {
            maps[now.x][now.y] = '.';
            now.step = now.step + 1;
            use[now.x][now.y] = 1;
            qu.push(now);//再次压入
            continue;
        }
        for(int i=0;i<4;i++)
        {
            Next.x = now.x + dir[i][0];
            Next.y = now.y + dir[i][1];
            Next.step = now.step + 1;
            if(check(Next.x,Next.y))
            {
                use[Next.x][Next.y] = 1;
                qu.push(Next);
            }
        }
    }
    printf("Poor ANGEL has to stay in the prison all his life.
");
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(use,0,sizeof(use));
        maps_store();
        bfs();
    }
}



解法二代码:


#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int maxsize = 210;
int n,m,dir[4][2] = {1,0,-1,0,0,1,0,-1},use[maxsize][maxsize];
char map[maxsize][maxsize];
struct node
{
    int x,y,time;
    friend bool operator < (node a,node b)//队列中排序的判断,注意写法
    {
        return a.time>b.time;
    }
} now,Next;

priority_queue <node> pr_qu;//优先队列

void map_store()
{
    for(int i=0; i<n; i++)
        cin>>map[i];
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            if(map[i][j] == 'r')
            {
                now.x = i;
                now.y = j;
                now.time = 0;
                use[now.x][now.y] = 1;
                return;
            }
        }
    }
}

bool check(int x,int y)
{
    if(x<0 || y<0 || x>=n || y>=m || map[x][y] == '#' || use[x][y] == 1)
        return false;
    else
        return true;
}

int bfs()
{
    while(!pr_qu.empty())
        pr_qu.pop();
    pr_qu.push(now);
    while(!pr_qu.empty())
    {
        now = pr_qu.top();
        if(map[now.x][now.y] == 'a')
            return now.time;
        for(int i=0; i<4; i++)
        {
            Next.x = now.x + dir[i][0];
            Next.y = now.y + dir[i][1];
            if(check(Next.x,Next.y))
            {
                if(map[Next.x][Next.y] == 'x')//注意这部分的位置
                    Next.time = now.time + 2;
                else
                    Next.time = now.time + 1;
                pr_qu.push(Next);
                use[Next.x][Next.y] = 1;
            }
        }
        pr_qu.pop();
    }
    return -1;//没有找到a时返回-1
}
int main()
{
    while(cin>>n>>m)
    {
        memset(use,0,sizeof(use));
        map_store();
        int Time = bfs();
        if(Time == -1)
            cout<<"Poor ANGEL has to stay in the prison all his life."<<endl;
        else
            cout<<Time<<endl;
    }
}


原文地址:https://www.cnblogs.com/GoldenFingers/p/9107375.html