1454:山峰和山谷

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38749759/article/details/86504146

1454:山峰和山谷


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 93     通过数: 28

【题目描述】

给定一个 n×n

的网格状地图,每个方格 (i,j)有一个高度 wij

​​ 。如果两个方格有公共顶点,则它们是相邻的。

定义山峰和山谷如下:

均由地图上的一个连通块组成;

所有方格高度都相同;

周围的方格(即不属于山峰或山谷但与山峰或山谷相邻的格子)高度均大于山谷的高度,或小于山峰的高度。

求地图内山峰和山谷的数量。特别地,如果整个地图方格的高度均相同,则整个地图既是一个山谷,也是一个山峰。

【输入】

第一行一个整数n(2≤n≤10002≤n≤10002≤n≤1000)

,表示地图的大小。

接下来 n

行每行 n 个整数表示地图。第 i 行有 n 个整数 wi1,wi2,…,win(0≤wij≤1 000 000 000),表示地图第 i

行格子的高度。

【输出】

输出一行两个整数,分别表示山峰和山谷的数量。

【输入样例】

5
8 8 8 7 7
7 7 8 8 7
7 7 7 7 7
7 8 8 7 8
7 8 8 8 8

【输出样例】

2 1

【提示】

样例1解释:

样例输入2:

5
5 7 8 3 1
5 5 7 6 6
6 6 6 2 8
5 7 2 5 8
7 1 0 1 7

样例输出2:

3 3

样例2解释:

山峰:8(两块),7

山谷:1,0,5

6 不是山峰也不是山谷:6所围成的块周围有比它大的7,也有比他小的2

其他同理

【来源】

信息学奥赛一本通

分析

广搜的剪枝 ,每个点进行广搜,每搜完一个点,把与它相连接的点标记,不重复的搜。

特别注意,如果整个地图方格的高度均相同,则整个地图既是一个山谷,也是一个山峰。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1010;
int mp[maxn][maxn];
int dir[][2]{0,1,0,-1,1,0,-1,0,1,-1,-1,-1,-1,1,1,1};
int vis[maxn][maxn];
int high,low;
int n;
int cnt;
struct node{
	int x;
	int y;
};
void bfs(int x1,int y1){
	bool sign1,sign2;	
	cnt=0;
	sign1=sign2=false;
	struct node  pre,now;
	pre.x=x1;     pre.y=y1;
	vis[x1][y1]=true;
	cnt++;
	queue<node> que;
	que.push(pre);
	while(!que.empty()){
		now=que.front();
		que.pop();
		for(int i=0;i<8;i++){
			pre.x=now.x+dir[i][0];
			pre.y=now.y+dir[i][1];
		
			if(pre.x>n||pre.y>n||pre.x<=0||pre.y<=0||(vis[pre.x][pre.y]&&mp[pre.x][pre.y]==mp[now.x][now.y]))
//标记已走过的坐标,且改坐标对应的值与之前的值相同
				continue;
			else if(mp[pre.x][pre.y]==mp[now.x][now.y]){
					que.push(pre);
					vis[pre.x][pre.y]=true;
					cnt++;
			}
			else{
				if(mp[now.x][now.y]>mp[pre.x][pre.y])
					sign1=true;
				else
					sign2=true;
			}
		}
	}

	if(sign1&&sign2)
		return;
	else if(sign1)
		high++;
	else if(sign2)
		low++;
	if(cnt==n*n)
		low++,high++;
	return;
}
int main()
{
	
	cin>>n;
	high=low=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			cin>>mp[i][j];
	memset(vis,false,sizeof(vis));
	for(int i=1;i<=n;i++){
	     for(int j=1;j<=n;j++){
			if(!vis[i][j])
				bfs(i,j);
			
					
	    }
	}
	cout<<high<<" "<<low<<endl;
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38749759/article/details/86504146