zoukankan      html  css  js  c++  java
  • Codeforces gym101755H Safe Path(bfs)

    题意:

    给以一个网格图,有起点终点和一些怪兽,可以上下左右走,不能走到距离怪兽曼哈顿距离为d以内的地方,问到终点最短路径

    n*m<=2e5,d<=2e5

    思路:

    因为n*m的范围,不能直接建2e5*2e5的图,所以要vector.resize()

    如果对每个怪兽都预处理的话,复杂度将是O(d2)

    所以我们可以让所有怪兽同时走,这样预处理只有O(nm),也可以证明不会漏情况

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<stack>
    #include<queue>
    #include<deque>
    #include<set>
    #include<vector>
    #include<map>
    #include<functional>
         
    #define fst first
    #define sc second
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lc root<<1
    #define rc root<<1|1
    #define lowbit(x) ((x)&(-x))
     
    using namespace std;
     
    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;
     
    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e6+100;
    const int maxm = 1e6+100;
    //const int inf = 0x3f3f3f3f;
    const int inf = 1e9+7;
    const db pi = acos(-1.0);
     
    
    vector<char>a[maxn];
    vector<int>v[maxn],vis[maxn],wall[maxn],tp[maxn];
    int n,m,d;
    int dx[5] = {0,-1,0,1};
    int dy[5] = {1,0,-1,0};
    bool ck(int x, int y){
        if(x>=1&&x<=n&&y>=1&&y<=m)return true;
        return false;
    }
    queue<pair<PI, int>>seetq;
    void seet(){
        
        while(!seetq.empty()){
            auto top = seetq.front();
            seetq.pop();
            int x = top.fst.fst;
            int y = top.fst.sc;
            int z = top.sc;
            //f(v[x][y])continue;
            //v[x][y]=1;
            if(z==d)continue;
            for(int i = 0; i < 4; i++){
                if(ck(x+dx[i],y+dy[i])&&v[x+dx[i]][y+dy[i]]==0){
                    seetq.push({{x+dx[i],y+dy[i]},z+1});
                    v[x+dx[i]][y+dy[i]]=1;
                }
            }
        }
        return;
    }
    PI s,t;
    char str[maxn];
    
    int main() {
        scanf("%d %d %d", &n, &m, &d);
        for(int i = 1; i <= n; i++){
            v[i].resize(m+1);
            a[i].resize(m+1);
            vis[i].resize(m+1);
            wall[i].resize(m+1);
            tp[i].resize(m+1);
        }
        
        //getchar();
        for(int i = 1; i <= n; i++){
            scanf("%s",str+1);
            for(int j = 1; j <= m; j++){
                v[i][j]=vis[i][j]=wall[i][j]=0;
                tp[i][j]=inf;
                char c = str[j];
                a[i][j] = c;
                if(c=='S'){
                    s = {i,j};
                }
                else if(c=='F'){
                    t = {i,j};
                }
                else if(c=='M'){
                    wall[i][j]=d+1;
                    seetq.push({{i,j},0});
                    v[i][j]=1;
                }
            }
        }
        seet();
        queue<pair<PI,int>>q;
        q.push({{s.fst,s.sc},0});
        int ans = -1;
        if(v[s.fst][s.sc]==1)return printf("-1"),0;
        q.push({{s.fst,s.sc},0});
        while(!q.empty()){
            auto top = q.front();
            q.pop();
            int x = top.fst.fst;
            int y = top.fst.sc;
            int z = top.sc;
            if(x==t.fst&&y==t.sc){
                ans=z;
                break;
            }
            if(vis[x][y])continue;
            vis[x][y]=1;
            for(int i = 0; i < 4; i++){
                int nx = x+dx[i];
                int ny = y+dy[i];
                if(ck(nx,ny)&&vis[nx][ny]==0&&v[nx][ny]!=1){
                    q.push({{nx,ny},z+1});
                }
            }
        }
        printf("%d",ans);
        return 0;
    }
    /*
    4
    2 2 3
    2 3 4
    1 4
    0
     */
  • 相关阅读:
    判断ascii码是什么的函数
    php curl
    js form settimeout
    windows php文件下载地址
    面试(3)
    [读码时间] 显示单击的坐标
    [读码时间] 模拟select控件
    [读码时间] 星级评分
    [读码时间] 事件练习:封闭兼容性添加,删除事件的函数
    [读码时间] 数组方法的使用
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/10757404.html
Copyright © 2011-2022 走看看