You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.6 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}