山峰和山谷
FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷。为了能够对旅程有一个安排,他想知道山峰和山谷的数量。给定一个地图,为FGD想要旅行的区域,地图被分为 n×n的网格,每个格子 (i,j)的高度 w(i,j)是给定的。若两个格子有公共顶点,那么它们就是相邻的格子,如与 (i,j)相邻的格子有(i−1,j−1),(i−1,j),(i−1,j+1),(i,j−1),(i,j+1),(i+1,j−1),(i+1,j),(i+1,j+1)。我们定义一个格子的集合 S为山峰(山谷)当且仅当:S 的所有格子都有相同的高度。S的所有格子都连通。对于 s属于 S,与 s相邻的 s′不属于 S,都有 ws>ws′(山峰),或者 ws<ws′(山谷)。
如果周围不存在相邻区域,则同时将其视为山峰和山谷。
你的任务是,对于给定的地图,求出山峰和山谷的数量,如果所有格子都有相同的高度,那么整个地图即是山峰,又是山谷。
输入格式
第一行包含一个正整数 n,表示地图的大小。
接下来一个 n×n 的矩阵,表示地图上每个格子的高度 w。
输出格式
共一行,包含两个整数,表示山峰和山谷的数量。
数据范围
1≤n≤1000
0≤w≤109
输入样例1:
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
输出样例1:
2 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
Solutions
代码读取网格 n 的维度和网格本身作为一组整数。 网格表示为整数 g 的二维数组,其中每个整数表示网格中单元格的高度。
bfs 函数由 main 函数调用,并使用广度优先搜索 (BFS) 算法将峰或谷中的所有单元格标记为已访问。 具体来说,该函数将作为峰或谷一部分的单元 (x, y) 的坐标作为输入,然后使用队列从该单元开始执行 BFS。 对于 BFS 期间访问的每个单元格,该函数在二维数组 st 中将单元格标记为已访问,并更新两个布尔变量 has_higher 和 has_lower 以分别指示峰或谷是否具有更高或更低高度的单元格。
在 main 函数中,代码初始化一个二维数组 st 以跟踪访问过哪些单元格,然后遍历网格中的每个单元格。 对于尚未访问过的每个单元格,该函数调用 bfs 函数将峰值或谷值中的所有单元格标记为已访问,并更新两个计数器峰值和谷值以跟踪网格中峰值和谷值的数量。
最后,main 函数输出 peak 和 valley 的值,分别表示网格中峰和谷的数量。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n;
int g[N][N];
bool st[N][N];
void bfs(int x, int y, bool &has_higher, bool &has_lower) {
queue<PII> q;
q.push(make_pair(x, y));
st[x][y] = true;
while (q.size()) {
PII t = q.front();
q.pop();
for (int i = t.first - 1; i <= t.first + 1; i ++ ) {
for (int j = t.second - 1; j <= t.second + 1; j ++ ) {
if (i < 0 || i >= n || j < 0 || j >= n) continue;
if (g[i][j] != g[t.first][t.second]) {
if (g[i][j] > g[t.first][t.second]) has_higher = true;
else has_lower = true;
}else if (!st[i][j]) {
q.push(make_pair(i, j));
st[i][j] = true;
}
}
}
}
}
int main() {
cin.tie(nullptr);
cout.tie(nullptr);
ios::sync_with_stdio(false);
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_higher = false, has_lower = false;
bfs(i, j, has_higher, has_lower);
if (!has_higher) peak ++;
if (!has_lower) valley ++;
}
}
}
cout << peak << ' ' << valley << endl;
return 0;
}