题解【洛谷P3456】[POI2007]GRZ-Ridges and Valleys

题面

考虑 \(\text{Flood Fill}\)

每次在 \(\text{BFS}\) 扩展的过程中增加几个判断条件,记录山峰和山谷的个数即可。

#include <bits/stdc++.h>

using namespace std;

int n, m, w[1003][1003], c1, c2;
bool st[1003][1003];
pair <int, int> q[1001 * 1001];
int hh, tt;

inline void bfs(int x, int y, bool &has_t, bool &has_l)
{
    hh = tt = 0;
    q[0] = (make_pair)(x, y); //队列初始化
    st[x][y] = true; //标记已访问
    while (hh <= tt) //队列不为空
    {
        pair <int, int> u = q[hh++]; //取出队头元素
        for (int i = u.first - 1; i <= u.first + 1; i+=1)
            for (int j = u.second - 1; j <= u.second + 1; j+=1) //向周围 8 个方向扩展
            {
                if (i < 1 || i > n || j < 1 || j > n) continue;
                if (w[i][j] > w[u.first][u.second])
                    has_t = true; //周围的高度有比它高的
                else if (w[i][j] < w[u.first][u.second])
                    has_l = true; //周围的高度有比它矮的
                else if (!st[i][j]) //高度相等且没有被标记访问过
                    st[i][j] = true, q[++tt] = (make_pair)(i, j); //标记已访问,并加入队列
            }
    }
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i+=1)
        for (int j = 1; j <= n; j+=1)
            cin >> w[i][j];
    for (int i = 1; i <= n; i+=1)
        for (int j = 1; j <= n; j+=1) //枚举每个点
            if (!st[i][j]) //当前点没有被标记
            {
                bool has_t = false, has_l = false;
                //标记周围有没有 比它高的 和 比它矮的
                bfs(i, j, has_t, has_l); //BFS 扩展
                if (!has_t) ++c1; //周围没有比它高的就是山峰
                if (!has_l) ++c2; //周围没有比它矮的就是山谷
            }
    cout << c1 << ' ' << c2 << endl; //输出山峰和山谷个数
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xsl19/p/12368300.html