BFS 搜索 Problem 1012 Rescue 拯救天使

Problem ID:1012 Rescue


简单题意:给出一个地图,其中有一个"a",代表angle,若干个"r",代表去营救angle的朋友,"x"标志敌人,"."标志可以行进的区域,"#"标志不可行进的区域。只可直行,不能斜向前进。走向"."耗时1,走向并击败"x"耗时2,求能拯救angle所需要的最短时间。如不能拯救,则输出"Poor ANGEL has to stay in the prison all his life."

解题思路形成过程:利用BFS,但所有能经过的区域都要搜索一遍(这是重点),因为"."区域和"x"区域耗时不同。
            用一个二维数组记录能到达每个区域的最短时间。
            在遍历过程中,如果按照某走法将要到达的某区域的所花费的总时间比之前记录的要大,则不走,从而进行剪枝。

感想:因为是所有"."和"x"区域都要遍历一遍,用DFS也可以。一开始没有考虑到这个条件,WA了一次,还是考虑的不够细致。

代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int cmap[201][201],mark[201][201];
int r1[201],r2[201];
int dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};
int aim_r,aim_c;
int n,m;
void bfs(int r,int c)
{
    queue<int>s;
    s.push(r);
    s.push(c);
    s.push(0);
    mark[r][c]=0;
    while(!s.empty())
    {
        int now_r=s.front();
        s.pop();
        int now_c=s.front();
        s.pop();
        int now_cnt=s.front();
        s.pop();
        for(int i=0;i<4;++i){
            int temp_r=now_r;
            int temp_c=now_c;
            int temp_cnt=now_cnt;
            temp_r+=dir[i][0];
            temp_c+=dir[i][1];
            if(cmap[temp_r][temp_c]==3)
                temp_cnt+=2;
            else
                temp_cnt++;
            if(temp_r>=0&&temp_r<n&&temp_c>=0&&temp_c<m)
                if(cmap[temp_r][temp_c]!=1&&cmap[temp_r][temp_c]!=5)
                    if(mark[temp_r][temp_c]>temp_cnt||mark[temp_r][temp_c]==-1)//所有"."和"x"区域必须全部搜索一遍.
                    {

                        s.push(temp_r);
                        s.push(temp_c);
                        s.push(temp_cnt);
                        mark[temp_r][temp_c]=temp_cnt;
                    }
        }
    }
}
int main()
{
   // freopen("2.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(mark,-1,sizeof(mark));
        int t=0;
        for(int i=0;i<n;++i)
            for(int j=0;j<m;++j){
                char temp;
                cin>>temp;
                if(temp=='r'){
                    cmap[i][j]=1;
                    r1[t]=i;
                    r2[t]=j;
                    ++t;
                }
                else if(temp=='a'){
                    cmap[i][j]=2;
                    aim_r=i;
                    aim_c=j;
                }
                else if(temp=='x')
                    cmap[i][j]=3;
                else if(temp=='.')        //可不写
                    cmap[i][j]=4;
                else if(temp=='#')
                    cmap[i][j]=5;
            }
        for(int i=0;i<t;++i)
            bfs(r1[i],r2[i]);
        int cmin=mark[aim_r][aim_c];
        if(cmin!=-1)
            printf("%d\n",cmin);
        else
            printf("Poor ANGEL has to stay in the prison all his life.\n");
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值