Gym 101755H Safe Path(bfs)

题目链接

题意:

给一个n*m的矩阵,矩阵中‘.'表示可通行,‘S'表示人出发 的地方,’F'表示人要到达的地方,‘M'表示恶魔在的地方,只要人在恶魔d步或d步以内能到达的地方,人就会被吃掉,问人是否能从S到达F,若能,输出最小步数,否则,输出-1;

思路:

先标记一下每个M在d步所能到达的所有地方,然后bfs;

用vector存图,用map标记;

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,m,d,sx,sy,ex,ey;

vector<string>vc;
map<pair<int,int>,int>mp;
pair<int,int>pa;
#define fi first
#define se second

bool ok(int x,int y){
    pa.fi=x,pa.se=y;
    if(x>=0&&x<n&&y>=0&&y<m&&!mp[pa]) return 1;
    return 0;
}

struct node{
    int x,y,z;
    node(int a,int b,int c){
        x=a,y=b,z=c;
    }
};

int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};

queue<node>q;

void bfsm(){
    while(q.size()){
        node p=q.front();
        q.pop();
        if(p.z>d) continue;
        if(!ok(p.x,p.y)) continue;
        pa.fi=p.x,pa.se=p.y;
        mp[pa]++;
        for(int i=0;i<4;i++){
            int nx=p.x+dx[i],ny=p.y+dy[i];
            if(!ok(nx,ny)) continue;
            q.push(node(nx,ny,p.z+1));
        }
    }
}

int bfs(){
    while(q.size()) q.pop();
    q.push(node(sx,sy,0));
    while(q.size()){
        node p=q.front();
        q.pop();
        if(!ok(p.x,p.y)) continue;
        if(p.x==ex&&p.y==ey) return p.z;
        pa.fi=p.x,pa.se=p.y;
        mp[pa]++;
        for(int i=0;i<4;i++){
            int nx=p.x+dx[i],ny=p.y+dy[i];
            pa.fi=p.x,pa.se=p.y;
            if(!ok(nx,ny)) continue;
            q.push(node(nx,ny,p.z+1));
        }
    }
    return -1;
}
int main(){
    scanf("%d%d%d",&n,&m,&d);
    string s;
    for(int i=0;i<n;i++) cin>>s,vc.push_back(s);
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(vc[i][j]=='S') sx=i,sy=j;
            else if(vc[i][j]=='F') ex=i,ey=j;
            else if(vc[i][j]=='M') q.push(node(i,j,0));
        }
    }
    bfsm();//标记每个m在d步能到达的所有地方
    int ans=bfs();
    cout<<ans<<endl;
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值