洛谷 P2919 [USACO08NOV] Guarding the Farm S 找山丘

题目表述似乎有点问题,该题目可以理解为找有几个山顶,每个山顶的高度都大于等于周围的高度,且向外延伸时高度降低。

问有多少个这样的山/山顶。

 

顺序剪枝:先排序,然后从高的开始搜索,搜到过的地方就不会再搜。而每个没被搜到过的地方必然存在一个新的山。

排除等效剪枝:如果被搜过则不用再搜了,其搜索是等效的。

#include <iostream> 
#include<cstdio>
#include<algorithm>
using namespace std;
struct dian{
	int x;
	int y;
	int v;
}s[500000];
bool cmp(dian x,dian  y){return x.v>y.v;}
int map[800][800];
int vis[800][800];
int x,y,n,m,now;
int ans;
int xc[8]={1,1,0,-1,-1,-1,0,1};
int yc[8]={0,1,1,1,0,-1,-1,-1};
void dfs(int x,int y){
	if(x<0||y<0||x>n||y>m){
		return ;
	}
	vis[x][y]=1;//遍历过的点标记,下次就不用遍历了 
	for(int i=0;i<=7;++i){
		if(map[x+xc[i]][y+yc[i]]<=map[x][y]&&!vis[x+xc[i]][y+yc[i]])
		dfs(x+xc[i],y+yc[i]);
	}
	return ;	
}
int main(){
	cin>>n>>m;
	int hight,cnt=0;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
		{
			scanf("%d",&hight);
			map[i][j]=hight;
			s[++cnt].x=i;
			s[cnt].y=j;
			s[cnt].v=hight;
		}
	//从高到低排序,高的先搜 
	sort(s+1,s+n*m+1,cmp);
	for(int i=1;i<=n*m;++i)
		if(!vis[s[i].x][s[i].y])
		{
			ans++;
			dfs(s[i].x,s[i].y);
		}
	cout<<ans;
	return 0;	
}

 

posted @ 2023-07-24 16:01  浪矢-CL  阅读(15)  评论(0编辑  收藏  举报