一、算法分析
这道题和POI2007的一道题目
GRZ-Ridges and Valleys
如出一辙,只是本题求的是山峰,POI那道题求的是山峰和山谷。当时POI那道题是自己在ACwing上面看到的,这里推荐一下ACwing这个网站,这个网站是之前的一个NOI金牌得主闫学灿创办的,里面很多题目有闫学灿大佬的视频讲解,讲的还是很好的。POI那道题就是自己看了视频才会的,所以这道题很受yxc大佬码风的影响。
简单来说就是一个找连通块问题,所以外层基本框架是统计所有的数字相同的连通块。但是不是所有连通块都是满足要求的,我们只记录外层没有比自己数字大的连通块的个数。详见代码及注释。
二、代码及注释
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#define r first
#define c second
using namespace std;
//对于某个山峰,首先其是一个连通块,所以核心还是找连通块的问题
//但是我们要找一种特殊的连通块,即周围没有大于等于其高度的连通块
const int N=755;
typedef pair<int,int> PII;
int G[N][N];
int n,m;
int ans;
int st[N][N];
queue<PII> q;
void bfs(int r,int c,int& has_higher){
while(!q.empty()) q.pop();
q.push({r,c});
st[r][c]=1;
while(q.size()){
PII t=q.front();
q.pop();
for(int i=t.r-1;i<=t.r+1;i++)
for(int j=t.c-1;j<=t.c+1;j++){
if(i==t.r && j==t.c) continue;
if(i<0 || i>=n || j<0 || j>=m) continue;
if(G[i][j]!=G[t.r][t.c]){ //这里和st无关
if(G[i][j]>G[t.r][t.c]) has_higher=1; //这里虽然已经判失败了,但是还是要继续跑bfs
}
else if(!st[i][j]) st[i][j]=1,q.push({i,j});
}
}
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++) cin>>G[i][j];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
if(!st[i][j]){
int has_higher=0;
bfs(i,j,has_higher);
if(!has_higher) ans++;
}
}
printf("%d",ans);
return 0;
}