山峰和山谷 Ridges and Valleys

Posted fangbozhen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了山峰和山谷 Ridges and Valleys相关的知识,希望对你有一定的参考价值。

https://loj.ac/problem/2653

题目描述

  给出一个n×n的数组,表示(i,j)的高度,定义山谷为周围一片的高度都大于它,且在它里的方格高度都相同;定义山峰为周围一片的高度都小于它,且其中的高度相同,求山峰数和山谷数。

思路

  我们选择bfs。我们每次选择一个未访问过的点作为起始点,访问和它高度相同的点所构成的连通块,在访问的过程中我们可以搜索到连通块的边界,所以搜索到边界后我们判断边界高度和这一片“平原”的高低,从而排除是山峰或山谷的可能。不过这道题最坑的一点是如果整一块区域的高度都相同那么这篇区域既是山峰也是山谷,需要特判。

代码

#include <bits/stdc++.h>
using namespace std;
struct aa

    int x,y;
    aa(int x=0,int y=0):x(x),y(y)
;
queue<aa> q;
int dx[9]=0,0,1,1,1,-1,-1,-1,dy[9]=1,-1,1,0,-1,1,0,-1;
bool f1,f2,vis[1100][1100];
int mp[1100][1100],n;
void bfs(int sx,int sy)

    vis[sx][sy]=1;
    q.push(aa(sx,sy));
    while(!q.empty())
    
        aa now=q.front();q.pop();
        for(int i=0;i<8;i++)
        
            int nx=now.x+dx[i],ny=now.y+dy[i];
            if(nx>0&&nx<=n&&ny>0&&ny<=n)
            
                if(mp[now.x][now.y]<mp[nx][ny])f1=0;
                if(mp[now.x][now.y]>mp[nx][ny])f2=0;
                if(!vis[nx][ny]&&mp[now.x][now.y]==mp[nx][ny])
                
                    vis[nx][ny]=1;
                    q.push(aa(nx,ny));
                
            
        
    

int main() 

    bool ff=1;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        
            scanf("%d",&mp[i][j]);
            if(mp[i][j]!=mp[1][1])ff=0;
        
    if(ff)
        printf("1 1");
    else
    
        int ans1=0,ans2=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(!vis[i][j])
                
                    f1=1;f2=1;
                    bfs(i,j);
                    if(f1)ans1++;
                    if(f2)ans2++;
                
        printf("%d %d",ans1,ans2);
    
    return 0;

 

以上是关于山峰和山谷 Ridges and Valleys的主要内容,如果未能解决你的问题,请参考以下文章

P3456 [POI2007]GRZ-Ridges and Valleys

[POI2007]山峰和山谷Grz

[FloodFill] aw1106. 山峰和山谷(bfs+FloodFill+模板题)

1106. 山峰和山谷变种的搜索 求连通块

bzoj1102: [POI2007]山峰和山谷Grz

在等高线地形图上识别山峰,山脊和山谷的方法都有哪些