• 登峰造极 题解


    一、题目:

    二、思路:

    首先这题一看就有打暴力的冲动。flood-fill搞一搞,拿到了70分。

    那么我们来讲一讲正解。

    首先我们将网格图转化成线性图后按高度从大到小排序。然后我们考虑这样两个点(i,j),其中i的高度大于j的高度。我们记i能走到的所有点为集合(S_i),记j能走到的所有点为集合(S_j),那么如果(S_i)(S_j)有交集,那么j就一定不可能是“登峰造极”。感性理解一下:高山峰能走过的点,低山峰一定能走到。所以(S_i)(S_j)一旦有交集,必有(S_isubseteq S_j)
    .
    那么我们按高度从大到小的顺序枚举每个点,标记它能走过的所有点。如果它能到一个已经被标记的点,它就一定不是“登峰造极”,否则就一定是“登峰造极”。

    显然,遇到已经被标记的点就不用再搜了,因为它能被比它高的点走到,所以它就也一定不是“登峰造极”。

    时间复杂度(O(n imes m))。如果算上排序的话应该是(O(nmlog_2(nm)))

    三、代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
     
    #define LL long long
    #define mem(s,v) memset(s,v,sizeof(s))
    #define FILEIN(s) freopen(s".in","r",stdin)
    #define FILEOUT(s) freopen(s".out","w",stdout)
     
    using namespace std;
     
    inline LL read(void){
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return f*x;
    }
     
    const int maxn=505;
     
    int n,m,ans;
    LL d;
     
    LL Map[maxn][maxn];
    
    pair<int,int>num[maxn*maxn];
    
    struct Node{
        int x,y,data;
        Node(){}
        Node(int _x,int _y,int _data):x(_x),y(_y),data(_data){}
        inline friend bool operator <(Node a,Node b){
            return a.data>b.data;
        }
    }ord[maxn*maxn];
     
    int dx[]={0,1,0,-1},dy[]={1,0,-1,0},cnt;
    
    int vis[maxn][maxn];
    
    inline int key(int x,int y){return (x-1)*m+y;}
    
    inline void dot(int K,int &x,int &y){
        x=num[K].first;
        y=num[K].second;
    }
    
    inline bool check(int x,int y){
        if(x<1||x>n||y<1||y>m)return false;
        return true;
    }
     
    void bfs(int stx,int sty){
        queue<int>q;
        q.push(key(stx,sty));
        vis[stx][sty]=++cnt;
        bool flag=false;
        int sum=0;
        while(q.size()){
            int nx,ny,K=q.front();q.pop();dot(K,nx,ny);
            if(Map[nx][ny]==Map[stx][sty])++sum;
            for(register int i=0;i<4;++i){
                int tx=nx+dx[i],ty=ny+dy[i];
                if(check(tx,ty)&&Map[tx][ty]>Map[stx][sty]-d){
                    if(vis[tx][ty]&&vis[tx][ty]!=cnt)flag=true;
                    else if(!vis[tx][ty]){
                        vis[tx][ty]=cnt;
                        q.push(key(tx,ty));
                    }
                }
            }
        }
        if(!flag){
            ans+=sum;
        }
    }
     
    int main(){
        // FILEIN("dfzj");FILEOUT("dfzj");
        n=read();m=read();d=read();
        for(register int i=1;i<=n;++i){
            for(register int j=1;j<=m;++j){
                Map[i][j]=read();
                ord[key(i,j)]=Node(i,j,Map[i][j]);
                num[key(i,j)].first=i;
                num[key(i,j)].second=j;
            }
        }
        sort(ord+1,ord+n*m+1);
        for(register int i=1;i<=n*m;++i){
            bfs(ord[i].x,ord[i].y);
        }
        cout<<ans<<endl;
        return 0;
    }
    
  • 相关阅读:
    交通综合改造工程EPC总承包项目
    二三维一体化地理信息平台
    NetCore3.1升级到Net5.0序列化方法过时问题
    windows server2012部署.net core IIS,页面报503,应用程序池自动停止。。。
    NetCore使用NPOI导入Word中的图片信息
    NetCore 使用 iTextSharp 读取 PDF 中的文字信息
    NetCore 在 Docker中文件路径找不到的问题
    Vue中数组list直接push的是对象而不是追加数据的问题
    netcore3.1增加阿里云OSS云存储服务
    Centos中Docker容器中程序访问宿主机Redis和Mysql
  • 原文地址:https://www.cnblogs.com/little-aztl/p/11181949.html
Copyright © 2020-2023  润新知