P3456 [POI2007] GRZ-Ridges and Valleys
背景
本人蒟蒻,只会写 DFS 。本题 BFS 更好
思路
这是一道很明显的搜索题,题目要求我们找到山峰和山谷
山峰? 不就是在这个高度周围没有比它跟高的地方
山谷? 不就是在这个高度周围没有比它更矮的地方
因此我们只需要用 \(DFS\) 遍历遇到的所有高度—在遍历的期间查询周围的高度是否有比它高的和比它矮的即可
注意: 各个山峰和山谷之间的高度是不同的!!并不是最高的是山峰最矮的是山谷
实现
在代码实现过程中可能会遇到的问题:
一: 按照正常思路,\(DFS\) 遍历过程中会把已经遍历过的点给赋值成其他值,来防止死递归和多次遍历。但本题在后面的深搜中还需要利用其高度,因此这里给出两种思路:
1. 多开一个布尔类型的数组来储存该节点是否遍历过。
2. 将原本的改成其的负数,在判断高度时加一绝对值即可(为什么会说这个方法,是因为本人太蒟蒻,没想出方法一,而想出了此方法)
二: 在 \(DFS\) 遍历中每到一个节点就对其上下左右等进行高度的判断,若有比他高的: \(flag1=true\) 若有比他矮的 \(flag2=true\) (初始皆为 \(false\) )
\(DFS\)代码实例:
void dfs(int x,int y){
a[x][y]=-a[x][y];
int dx,dy;
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
dx=x+i;
dy=y+j;
if(dx>=1 && dx<=n && dy>=1 && dy<=n && abs(a[dx][dy])>abs(a[x][y])){
flag1=true;
}
if(dx>=1 && dx<=n && dy>=1 && dy<=n && abs(a[dx][dy])<abs(a[x][y])){
flag2=true;
}
if(dx>=1 && dx<=n && dy>=1 && dy<=n && a[dx][dy]==q){
dfs(dx,dy);
}
}
}
return;
}
(记得判断越界!!!)
三: 最后在 \(DFS\) 结束后判断
\(1.\)若既有比他高的又有比它矮的,那他啥也不是 \(if\)(\(flag1\) && \(flag2\))
\(1.\)若有比他高的却没有比它矮的,那他就是山谷 \(if\)(\(flag1\) && \(!flag2\))
\(1.\)若有比他矮的却没有比它高的,那他就是山峰 \(if\)(\(!flag1\) && \(flag2\))
注意要特判是否为平地(及高度一致)那么山峰和山谷都是1
代码:
#include<bits/stdc++.h>
using namespace std;
int a[1001][1001];
int ans1,ans2,q;
int n;
bool flag1,flag2,flag;
void dfs(int x,int y){
a[x][y]=-a[x][y];
int dx,dy;
for(int i=-1;i<=1;i++){
for(int j=-1;j<=1;j++){
dx=x+i;
dy=y+j;
if(dx>=1 && dx<=n && dy>=1 && dy<=n && abs(a[dx][dy])>abs(a[x][y])){
flag1=true;
}
if(dx>=1 && dx<=n && dy>=1 && dy<=n && abs(a[dx][dy])<abs(a[x][y])){
flag2=true;
}
if(dx>=1 && dx<=n && dy>=1 && dy<=n && a[dx][dy]==q){
dfs(dx,dy);
}
}
}
return;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
a[i][j]+1;
if(a[i][j]!=a[1][1]){
flag=true;
}
}
}
if(!flag){
cout<<1<<" "<<1;
return 0;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(abs(a[i][j])!=-a[i][j] ){
flag1=flag2=false;
q=a[i][j];
dfs(i,j);
if(flag1 && !flag2){
ans2++;
}
else if(!flag1 && flag2){
ans1++;
}
}
}
}
if(ans2==2){
cout<<ans1<<" "<<3;
return 0;
}
cout<<ans1<<" "<<ans2;
return 0;
}
标签:Valleys,&&,flag1,int,POI2007,GRZ,遍历,dx,dy
From: https://www.cnblogs.com/XichenOC/p/18682325