题号1454
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int h[N][N], dir[8][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {-1, -1}, {-1, 1}, {1, 1}, {1, -1}};
int n;
bool st[N][N];
queue<PII> q;
void bfs(int x, int y, bool& r1, bool& r2)
{
st[x][y] = true;
q.push({x, y});
while(q.size()) {
auto t = q.front();
q.pop();
for(int i = 0; i < 8; i++) {
int xx = t.x + dir[i][0], yy = t.y + dir[i][1];
// 如果出界就继续
if(xx < 1 || xx > n || yy < 1 || yy > n) continue;
// 如果扩展出的和现在的高度不相等
if(h[xx][yy] != h[t.x][t.y]) {
//联通快周围不相等的值大于联通快的话就说明当前联通快不能成为山峰
if(h[xx][yy] > h[t.x][t.y]) r1 = true;
//联通快周围不相等的值小于联通快的话就说明当前联通快不能成为山谷
else r2 = true;
} else if(!st[xx][yy]) {
st[xx][yy] = true;
q.push({xx, yy});
}
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
cin >> h[i][j];
int sf = 0, sg = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(!st[i][j]) {
bool r1 = false, r2 = false;
bfs(i, j, r1, r2);
//如果当前联通块周围都比联通快的值小说明当前联通块是山峰
if(!r1) sf++;
//如果当前联通块周围都比联通快的值大说明当前联通块是山谷
if(!r2) sg++;
}
}
cout << sf << " " << sg << endl;
return 0;
}