ZOJ 1649 Rescue

本文探讨了一种解决迷宫救援问题的算法,目标是在最少时间内到达被困者的位置。通过深搜并以时间作为关键参数,优化路径选择以实现救援任务。算法详细解释了如何在迷宫中导航,利用特定的结构体和队列来计算到达目标所需的最短时间。实例输入演示了算法应用的具体步骤和输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 


这道题可以看出是一道深搜的题目,但是也注意到一点,就是如果按普通的深搜会搜出最短路径的的最短时间,但是最短路径对应的时间不一定是最短时间,这是显然的,所以我们在深搜的时候就要以时间作为进队列的条件,如果通过某一个路径走到该点的时间比之前少就把这个点入队,以该点去更新其他点。这样到最后的队列为空的时候,那么记录的每一个点对应的时间就是最短时间了,具体看代码,相关说明有相应的注释:

#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f

const int maxn=200+10;

int dir[4][2]={{0,1}, {1,0}, {0,-1}, {-1,0}};
char map[maxn][maxn];
//bool vis[maxn][maxn];
int time1[maxn][maxn];
int N,M;
int ox,oy,fx,fy,num;
struct point//结构体,到某个点的坐标,步数,时间
{
    int x,y;
    int step;
    int time;
};
queue<point> que;

int BFS(point start)
{
    point head;

    que.push(start);
    map[start.x][start.y]='#';

    while(!que.empty())
    {
        head=que.front();
        que.pop();

        for(int i=0;i<4;i++)
        {
            int dx,dy;

            dx=head.x+dir[i][0];
            dy=head.y+dir[i][1];

            if((dx>=0)&&(dx<=N-1)&&(dy>=0)&&(dy<=M-1)&&map[dx][dy]!='#')
            {
                point t;
                t.x=dx; t.y=dy;
                t.time=head.time+1;
                t.step=head.step+1;

                if(map[dx][dy]=='x')    { t.time++;}

                if(t.time<time1[dx][dy])//如果该点的时间变小就入队去更新其他点
                {
                    time1[dx][dy]=t.time;
                    que.push(t);
                }
            }
        }
    }

    return time1[fx][fy];
}

int main()
{
//    freopen("s","r",stdin);

    while(scanf("%d%d",&N,&M)!=EOF)
    {
        getchar();
  //      memset(vis,0,sizeof(vis));
        memset(time1,0x3f,sizeof(time1));//一开始时间全部都是无穷大
        while(!que.empty())    { que.pop();}//保证每次队列为空

        for(int i=0;i<N;i++)
            scanf("%s",map[i]);
        for(int i=0;i<N;i++)
            for(int j=0;j<M;j++)
            {
                if(map[i][j]=='r')  {  ox=i; oy=j;}//找到起点
                if(map[i][j]=='a')  {  fx=i; fy=j; map[i][j]='.';}//找到终点
            }
        int res;
        point start;

        start.x=ox; start.y=oy; start.time=0; start.step=0;
        res=BFS(start);
        time1[ox][oy]=0;

        if(res<INF)
            printf("%d\n",res);
        else
            printf("Poor ANGEL has to stay in the prison all his life.\n");
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值