山峰和山谷 Ridges and Valleys

题目描述

思路

一开始看这道题目,也不是很会,谁会把统计之类的问题和bfs联系在一起,没有开始的状态,没有结束的状态,题目中连一个最短之类的词也没有出现。
然后统计嘛,题目中说了方格高度都相同,就把周围的点都看一遍和这个点高度相同的就入队,把高度相同的点都打上浏览的标记。看的过程中,既有比它小的,也有比它大的,那么这种高度的点就不是我们要统计的答案,只有比它小的,或只有比它大的,那么就是我们要统计的。可以设置两个标记,标记看的过程中有没有比它小的,比它大的。
然后就是只有一个高度的时候,因为两个标记都不满足,那么都加1。
然后就是这种题目感觉dfs和bfs都可以做,好像还有一种洪泛法的方法也可以解决。
然后就是抱怨一下bfs有套路,比起dfs要简单,dfs写起来容易,但是怎么表示每一层的状态就比较难,再加上剪枝之类的,qwq······

代码

#include <cstdio>
#include <cstring>
#include <queue>

int n;
int mp[1005][1005], vis[1005][1005], obs[1005][1005];
int dirx[] = {0, -1, -1, -1, 0, 1, 1, 1, 0};
int diry[] = {0, -1,  0,  1, 1, 1, 0,-1,-1};
struct Node {
    int x, y;
} tmp, cur;
std::queue<Node> q;
int lows, highs;
inline int read() {
    int s = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') ch = getchar();
    while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
    return s * f;
}

bool valid(int x, int y) {
    if (x < 1 || x > n) return false;
    if (y < 1 || y > n) return false;
    return true;
}

void bfs(int x, int y) {
    while (!q.empty()) q.pop();
    tmp.x = x, tmp.y = y;
    q.push(tmp);
    vis[x][y] = 1;
    int z = mp[x][y];
    bool low = false, high = false;
    while (!q.empty()) {
        cur = q.front();
        q.pop();
        for (int i = 1; i <= 8; ++i) {
            tmp.x = cur.x + dirx[i];
            tmp.y = cur.y + diry[i];
            if (valid(tmp.x, tmp.y)) {
                int tz = mp[tmp.x][tmp.y];
                if (tz < z) low = true;
                if (tz > z) high = true;
                if (tz == z && !vis[tmp.x][tmp.y]) {
                    q.push(tmp);
                    vis[tmp.x][tmp.y] = 1;
                }
            }
        }
    }
    if (!low) lows++;
    if (!high) highs++;
}

int main() {
    n = read();
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            mp[i][j] = read();
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            if (!vis[i][j]) bfs(i, j);
        }
    }
    printf("%d %d", highs, lows);

    return 0;
}

原文地址:https://www.cnblogs.com/liuzz-20180701/p/11610243.html

时间: 2024-07-31 10:30:48

山峰和山谷 Ridges and Valleys的相关文章

BZOJ1102: [POI2007]山峰和山谷Grz

1102: [POI2007]山峰和山谷Grz Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 436  Solved: 227[Submit][Status] Description FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷.为了能够让他对他的旅程有一个安排,他想知道山峰和山谷的数量. 给定一个地图,为FGD想要旅行的区域,地图被分为n*n的网格,每个格子(i,j) 的高度w(i,j)是给定的. 若两个格子有公共顶点,那么他们就

【bfs】BZOJ1102- [POI2007]山峰和山谷Grz

最后刷个水,睡觉去.Bless All! [题目大意] 给定一个地图,为FGD想要旅行的区域,地图被分为n*n的网格,每个格子(i,j) 的高度w(i,j)是给定的.若两个格子有公共顶点,那么他们就是相邻的格子.(所以与(i,j)相邻的格子有(i?1, j?1),(i?1,j),(i?1,j+1),(i,j?1),(i,j+1),(i+1,j?1),(i+1,j),(i+1,j+1)).我们定义一个格子的集合S为山峰(山谷)当且仅当:1.S的所有格子都有相同的高度.2.S的所有格子都联通3.对于

【BZOJ 1102】 [POI2007]山峰和山谷Grz

1102: [POI2007]山峰和山谷Grz Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 495  Solved: 263 [Submit][Status][Discuss] Description FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷.为了能够让他对他的旅程有一个安排,他想知道山峰和山谷的数量. 给定一个地图,为FGD想要旅行的区域,地图被分为n*n的网格,每个格子(i,j) 的高度w(i,j)是给定的. 若两个格子

BZOJ 1102 POI2007 山峰和山谷Grz Floodfill

题目大意:给定一张地势图,求山峰和山谷的数量 直接Floodfill--注意DFS会爆栈,用BFS才能过 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1010 using namespace std; int n,ans1,ans2,a[M][M]; bool flag,v[M][M]; /* void Floodfill(in

[POI2007]山峰和山谷Grz

Description FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷.为了能够让他对他的旅程有一个安排,他想知道山峰和山谷的数量.给定一个地图,为FGD想要旅行的区域,地图被分为\(n\times n\)的网格,每个格子(i,j) 的高度w(i,j)是给定的.若两个格子有公共顶点,那么他们就是相邻的格子.(所以与(i,j)相邻的格子有(i-1, j-1),(i-1,j),(i-1,j+1),(i,j-1),(i,j+1),(i+1,j-1),(i+1,j),(i+1,j+1)).我

P3456 [POI2007]GRZ-Ridges and Valleys

题意翻译 给定一个地图,为小朋友想要旅行的区域,地图被分为n*n的网格,每个格子(i,j) 的高度w(i,j)是给定的.若两个格子有公共顶点,那么他们就是相邻的格子.(所以与(i,j)相邻的格子有(i-1, j-1),(i-1,j),(i-1,j+1),(i,j-1),(i,j+1),(i+1,j-1),(i+1,j),(i+1,j+1)).我们定义一个格子的集合S为山峰(山谷)当且仅当: 1.S的所有格子都有相同的高度. 2.S的所有格子都联通3.对于s属于S,与s相邻的s’不属于S.都有ws

1281 山峰和旗子

用一个长度为N的整数数组A,描述山峰和山谷的高度.山峰需要满足如下条件, 0 < P < N - 1 且 A[P - 1] < A[P] > A[P + 1]. 现在要在山峰上插上K个旗子,并且每个旗子之间的距离 >= K,问最多能插上多少个旗子(即求K的最大值).两个山峰之间的距离为|P - Q|. 以上图为例,高度为:1 5 3 4 3 4 1 2 3 4 6 2.其中可以作为山峰的点为:1 3 5 10. 放2面旗子, 可以放在1 和 5. 放3面旗子, 可以放在1 5

51Nod1285 山峰和分段

Problem 用一个长度为N的整数数组A,描述山峰和山谷的高度.山峰需要满足如下条件, 0 < P < N - 1 且 A[P - 1] < A[P] > A[P + 1]. 现在要将整个山分为K段,要求每段的点数都一样,且每段中都至少存在一个山峰,问最多可以分为多少段. Solution 枚举因数,前缀和优化查询. 复杂度是因子之和,试了一下,1e6之内一个大于5*n的也没有,最大比率4.5多一点. Code #include<stdio.h> #include&l

51Nod--1285-山峰和分段

1285 山峰和分段 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 用一个长度为N的整数数组A,描述山峰和山谷的高度.山峰需要满足如下条件, 0 < P < N - 1 且 A[P - 1] < A[P] > A[P + 1]. 以上图为例,高度为:1 5 3 4 3 4 1 2 3 4 6 2. 现在要将整个山分为K段,要求每段的点数都一样,且每段中都至少存在一个山峰,问最多可以分为多少段. In