Files
python/TangDou/AcWing/FloodFill/1106_bcj_2.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

88 lines
2.6 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
const int M = N * N;
int n;
int h[N][N];
int st[M][2]; // 第一维:并查集编号,第二维:0:附近的最小值,1:附近的最大值
// 1132 ms
int dx[] = {0, 1, 1, 1}; // 1右 2下 3右下 4左下
int dy[] = {1, 0, 1, -1};
int p[M];
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 根据坐标获取并查集的编号
void getXy(int num, int &x, int &y) {
x = (num - 1) / n + 1;
y = (num - 1) % n + 1;
}
// 根据并查集的编号获取坐标
int getNum(int x, int y) {
return (x - 1) * n + y;
}
int valley, peak;
int main() {
cin >> n;
// 初始化并查集
// i为每个格子在并查集中的编号,编号策略为 (i-1)*n+j
for (int i = 0; i < M; i++) p[i] = i; // 每个人都是自己的祖先
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
cin >> h[i][j];
int num = getNum(i, j);
st[num][0] = st[num][1] = h[i][j]; // 初始化
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
for (int k = 0; k < 4; k++) {
int x = i + dx[k], y = j + dy[k];
if (x == 0 || y == 0 || x > n || y > n) continue;
// 编号
int a = getNum(i, j), b = getNum(x, y);
// 族长
int pa = find(a), pb = find(b);
// 记录我们家族周围最小的
if (h[i][j] > h[x][y]) {
st[pa][0] = min(st[pa][0], h[x][y]);
st[pb][1] = max(st[pb][1], h[i][j]);
}
// 记录我们家族周围最大的
if (h[i][j] < h[x][y]) {
st[pa][1] = max(st[pa][1], h[x][y]);
st[pb][0] = min(st[pb][0], h[i][j]);
}
if (h[i][j] == h[x][y]) {
if (pa != pb) { // 合并并查集
p[pa] = pb;
st[pb][0] = min(st[pb][0], st[pa][0]);
st[pb][1] = max(st[pb][1], st[pa][1]);
}
}
}
}
// 没有比自己高的,山峰
// 没有比自己矮的,山谷
for (int i = 1; i <= n * n; i++) {
if (p[i] == i) {
int x, y;
getXy(i, x, y);
if (st[i][0] == h[x][y]) valley++;
if (st[i][1] == h[x][y]) peak++;
}
}
printf("%d %d\n", peak, valley);
return 0;
}