地牢逃脱

给定一个 n 行 m 列的地牢,其中 '.' 表示可以通行的位置,'X' 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上。地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。

 

在答题之前需要明确本题的题意,第一个是出口的问题,不是边界上的‘.’是出口,而是所有‘.’都可能是出口(除了起始的那个‘.',如果原地不动或者转了一圈之后回到原点,都表示这条路径没有出口,当然如果能转一圈,就一定会经过其他‘.’,则有出口)。第二个是求最大值的问题,将能到达某个‘.’的最短次数记录下来(如何保证最短,这里给定的是跳的长度,跳的最短次数是确定的,广度优先搜索的结果就是最短),在所有的这些能到达各个‘.’的路径中输出最大的次数,即需要移动的次数。需要遍历到所有的‘.’,因为所有的‘.’都可能为出口,我们输出的是最糟糕的情形(原地不动,或者有些‘.’到不了,就输出-1,其他情形则输出移动次数最多的那种)

主要思想是广度优先,代码如下

#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
#include<queue>
using namespace std;
 
int main()
{
    int n,m,x,y,k;  //输入
    cin>>n>>m;
    vector<vector<char>> ves(n,vector<char>(m,'.'));
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            cin>>ves[i][j];
        }
    cin>>x>>y;
    cin>>k;
    using PII=pair<int,int>;
    vector<PII> step(k,PII(0,0));
    for(int i=0;i<k;i++){
        cin>>step[i].first>>step[i].second;
    }
    //BFS求解
    queue<PII> qu;
    qu.push(PII(x,y));
    vector<vector<int> >reach(n,vector<int>(m,-1));
    reach[x][y]=0;
    while(!qu.empty()) {
        PII temp=qu.front();
        qu.pop();
         for(int i=0;i<step.size();i++){
             int xt=temp.first+step[i].first;
             int yt=temp.second+step[i].second;
             if(xt>=0&&xt<n&&yt>=0&&yt<m&&ves[xt][yt]=='.'&&reach[xt][yt]==-1){
                 reach[xt][yt]=reach[temp.first][temp.second]+1;
                 qu.push(PII(xt,yt));
             }
         }
    }
    int maxL=0;
    for(int i=0;i<n&&maxL!=-1;i++)
        for(int j=0;j<m;j++){
            if(reach[i][j]!=-1){
                maxL=max(maxL,reach[i][j]);
            }else if(ves[i][j]=='.'){
               maxL=-1;
                break;
            }
        }
    cout<<maxL<<endl;
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值