欲望以提升热忱,毅力以磨平高山!|

XichenOC

园龄:1个月粉丝:4关注:0

📂题解
🔖搜索
2025-01-20 18:53阅读: 3评论: 0推荐: 0

P3456 [POI2007] GRZ-Ridges and Valleys

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;
}

本文作者:XichenOC

本文链接:https://www.cnblogs.com/XichenOC/p/18682325

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   XichenOC  阅读(3)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起