>Link
ybtoj山峰与山谷
>解题思路
BFS总体思路:对于每一个没有搜到过的点进行bfs,把遇到的四周相同高度的点加入队列,遇到不同的,用两个变量记录周围高的和低的的个数。最后如果周围没有高的,说明此区域是山峰,如果周围没有低的,说明是山谷,否则什么也不是(这样子处理更加方便)
这里有一个小细节(又是zzl巨爷帮我改的),如果搜索过的在后面的bfs中就不用加入队列的,不然会tle
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 2010
using namespace std;
const int xx[8] = {
-1, -1, -1, 0, 0, 1, 1, 1}, yy[8] = {
-1, 0, 1, -1, 1, -1, 0, 1};
int n, a[N][N], head, tail, qx[N * N], qy[N * N], ans[5];
bool v[N][N], mark[N][N];
void bfs (int x, int y)
{
mark[x][y] = 1;
head = 0, tail = 1;
qx[1] = x, qy[1] = y, v[x][y] = 1;
int maxn = 0, minn = 0;
while (head < tail)
{
head++;
int ux = qx[head], uy = qy[head];
for (int i = 0; i < 8; i++)
{
int tx = ux + xx[i], ty = uy + yy[i];
if (tx < 1 || ty < 1 || tx > n || ty > n)
continue;
if (a[ux][uy] == a[tx][ty])
{
if (!mark[tx][ty])
{
mark[tx][ty] = 1;
tail++; qx[tail] = tx, qy[tail] = ty;
}
}
else
{
if (a[tx][ty] > a[ux][uy]) maxn++;
else minn++;
}
}
}
if (!maxn) ans[1]++;
if (!minn) ans[2]++;
}
int main()
{
scanf ("%d", &n);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) scanf ("%d", &a[i][j]);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (!mark[i][j]) bfs (i, j);
printf ("%d %d", ans[1], ans[2]);
return 0;
}