AcWing 1106. 山峰和山谷
原题链接
算法标签
BFS Flood Fill
思路
样例解释
思路
从前向后遍历
对于每个位置
判断其四周(未出界)位置,若不存在高于该位置的点 ,则属于山峰。若不存在低于该位置的点 ,则属于山谷。
#include<bits/stdc++.h>
#define int long long
#define rep(i, a, b) for(int i=a;i<b;++i)
#define Rep(i, a, b) for(int i=a;i>b;--i)
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1005;
int g[N][N];
PII p[N*N];
int n;
bool st[N][N];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
void put(int x) {
if(x<0) putchar('-'),x=-x;
if(x>=10) put(x/10);
putchar(x%10^48);
}
void dfs(int sx, int sy, bool &higher, bool &lower){
int hh=0, tt=0;
st[sx][sy]=true;
p[0]={sx, sy};
while(hh<=tt){
PII t=p[hh++];
rep(i, t.x-1, t.x+2){
rep(j, t.y-1, t.y+2){
// 去除中心位置
if(i==t.x&&j==t.y){
continue;
}
// 去除出界位置
if(i<0||i>=n||j<0||j>=n){
continue;
}
// 山脉边界
if(g[i][j]!=g[t.x][t.y]){
if(g[i][j]>g[t.x][t.y]){
lower=true;
}else{
higher=true;
}
}
// 若尚未遍历过 该位置入队并标记
else if(!st[i][j]){
p[++tt]={i, j};
st[i][j]=true;
}
}
}
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
n=read();
rep(i, 0, n){
rep(j, 0, n){
g[i][j]=read();
}
}
int va=0, peak=0;
rep(i, 0, n){
rep(j, 0, n){
bool higher=false, lower=false;
if(!st[i][j]){
dfs(i, j, higher, lower);
// 由于可能即属于山峰 同时属于山谷 故使用if if 判断
if(!higher){
peak++;
}
if(!lower){
va++;
}
}
}
}
printf("%lld %lld", va, peak);
return 0;
}
参考文献
AcWing 1106. 山峰和山谷y总视频讲解
AcWing 1106. 山峰和山谷y总代码
原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈