河南农业大学oj–天琴座的高雅
题目描述
给你一个地图,地图被分为nn的网格,每个格子都有一个高度w,并且每个格子与其上下左右,左上,左下,右上,右下八个方向的格子都是相邻的.
如果一片相邻的区域,这个区域所有格子高度相同,并且周围格子都比这片区域低,则为凸起。反之则为凹陷。现在想请你找到这个地图中凸起和凹陷的数量。如果所有格子都有相同的高度,那么整个地图即是凸起,又是凹陷。
输入
输入的第一行包含一个正整数n,表示地图的大小(1<=n<=1000)。接下来一个nn的矩阵,表示地图上每个格子的高
度。(0<=w<=1e9)
输出
输出两个用空格隔开的整数 ,表示凸起和凹陷的数量。
样例输入 Copy
5
3 3 3 2 2
2 2 3 3 2
2 2 2 2 2
2 3 3 2 3
2 3 3 3 3
样例输出 Copy
2 1
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 100;
int dir[8][2] = { 1, 0, 1, 1, 0, 1, -1, 1, -1, 0, -1, -1, 0, -1, 1, -1 };
int a[N][N], n;
bool vis[N][N];
int s1, s2;
int BFS(int x, int y) {
queue <pair <int, int>> q;
q.push({ x, y });
vis[x][y] = true;
bool ok1 = false, ok2 = false;
while (!q.empty()) {
pair <int, int> now = q.front();
q.pop();
int nx = now.first, ny = now.second;
for (int i = 0; i < 8; i++) {
int xx = nx + dir[i][0];
int yy = ny + dir[i][1];
if (xx < 1 || xx > n || yy < 1 || yy > n)
continue;
if (a[xx][yy] == a[nx][ny] && !vis[xx][yy]) {
vis[xx][yy] = true;
q.push({ xx, yy });
}
if (a[xx][yy] > a[nx][ny])
ok1 = true;
else if (a[xx][yy] < a[nx][ny])
ok2 = true;
}
}
if (ok1 && !ok2)
return 1;
else if (!ok1 && ok2)
return -1;
else
return 0;
}
int main()
{
set <int> st;
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%d", &a[i][j]);
st.insert(a[i][j]);
}
}
if (st.size() == 1)
puts("1 1"), exit(0);
int ans[2] = { 0, 0 };
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (vis[i][j])
continue;
int now = BFS(i, j);
if (now > 0)
ans[0]++;
else if (now < 0)
ans[1]++;
}
}
printf("%d %d\n", ans[1], ans[0]);
return 0;
}