山峰和山谷 题型:求特殊连通块的个数

83 阅读2分钟

P3456 [POI2007] GRZ-Ridges and Valleys - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题让我们找地图上的山谷和山峰的数量。

周围都比自己高的话,自己就是山峰,周围都比自己低的话自己就是山谷。样例中有两个山峰一个山谷: image.png

还有一种情况,就是周围即有比自己高的又有比自己低的那自己就不是山峰又不是山谷,如下图所示,7是山谷,9是山峰,8既不是山峰也不是山谷。题目只让我们求山峰和山谷的数量,对于这种既不是山峰又不是山谷的对答案没有贡献,我们不考虑: image.png

code

两个bfs()函数用哪个都行

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int, int>PII;
int n;
const int N = 1010, M = N * N;
int g[N][N];
bool  st[N][N];
PII q[M];
typedef pair<int, int> PII;

int dx[10] = { 0,0,1,1,1,-1,-1,-1 }, dy[10] = { 1,-1,0,-1,1,0,-1,1 };
void bfs(int x, int y, bool& has_higer, bool& has_lower)
{
	int hh = 0, tt = 0;
	q[0] = { x,y };
	st[x][y] = true;

	while (hh <= tt)
	{
		PII t = q[hh++];

		for (int i = 0; i<8; i++)
		{
			int tx = t.x + dx[i], ty = t.y + dy[i];
			if (tx < 0 || tx >= n || ty < 0 || ty >= n )continue;
			if (g[tx][ty] != g[t.x][t.y])  //如果和旁边不一样高,那就判断一下当前位置是山峰还是山谷
			{
				if (g[tx][ty] > g[t.x][t.y]) has_higer = true;   //如果当前位置比欠他1点高 ,那么就是山峰
				else has_lower = true;
			}
			else if(!st[tx][ty]) 
			{
				q[++tt] = { tx,ty };
				st[tx][ty] = true;
			}

		}
	}
}
//void bfs(int x, int y, bool& has_higer, bool& has_lower)
//{
//	int hh = 0, tt = 0;
//	q[0] = { x,y };
//	st[x][y] = true;
//
//	while(hh<=tt)
//	{
//		PII t = q[hh++];
//		for (int i = t.x - 1; i <= t.x + 1; i++)
//		{
//			for (int j=t.y-1;j<=t.y+1;j++)
//			{
//				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]) has_higer = true;   //如果当前位置比欠他1点高 ,那么就是山峰
//					else has_lower = true;
//				}
//				else if (!st[i][j])
//				{
//					q[++tt] = { i,j };
//					st[i][j] = true;
//				}
//			}
//		}
//	}
//}

int main()
{
	 cin >> n;
	 for (int i = 0; i < n; i++)
		 for (int j = 0; j < n; j++)
			 cin >> g[i][j];


	 int peak = 0, valley = 0;  //山峰 山谷
	 for (int i = 0; i < n; i++)
	 {
		 for (int j = 0; j < n; j++)
		 {
			 if (!st[i][j])
			 {
				 bool has_higer=false, has_lower = false;
				 bfs(i,j,has_higer,has_lower);
				 if (!has_higer) peak++;  //是山峰
				 if (!has_lower) valley++; //是山谷
			 }
		 }
	 }



	 cout << peak << " " << valley << endl;
	return 0;
}