AcWing 1106. 山峰和山谷 bfs+思维

AcWing 1106. 山峰和山谷

FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷。

为了能够对旅程有一个安排,他想知道山峰和山谷的数量。

给定一个地图,为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 为山峰(山谷)当且仅当:

S 的所有格子都有相同的高度。
S 的所有格子都连通。
对于 s 属于 S,与 s 相邻的 s′ 不属于 S,都有 ws>ws′(山峰),或者 ws<ws′(山谷)。
如果周围不存在相邻区域,则同时将其视为山峰和山谷。
你的任务是,对于给定的地图,求出山峰和山谷的数量,如果所有格子都有相同的高度,那么整个地图即是山峰,又是山谷。

输入格式
第一行包含一个正整数 n,表示地图的大小。

接下来一个 n×n 的矩阵,表示地图上每个格子的高度 w。

输出格式
共一行,包含两个整数,表示山峰和山谷的数量。

数据范围
1≤n≤1000,
0≤w≤109

这道题求的是山峰数和山谷数,我们发现山峰和山谷的限定条件是周围的都比他大,要么比他小,高度相等,所以我们在原有的bfs模板增加几个限定条件就可,我们在bfs的时候,我们把高度比它高的数量设为high,高度比它低的设为low,如果high或Low为0,则就增加山峰/山谷数。

代码如下:

#include<iostream>
#include<queue>
#define x first
#define y second
using namespace std;

typedef pair<int,int> PII;
const int N=1010;

int g[N][N];
bool st[N][N];
int dx[8]={0,1,0,-1,1,1,-1,-1};
int dy[8]={1,0,-1,0,1,-1,1,-1};
int n;
int res,cnt;

void bfs(int sx,int sy)
{
    st[sx][sy]=true;
    queue<PII> q;
    q.push({sx,sy});
    int h=g[sx][sy];
    int high=0,low=0;
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        for(int i=0;i<8;i++)
        {
            int tx=t.x+dx[i];
            int ty=t.y+dy[i];
            if(tx<1||tx>n||ty<1||ty>n)
            continue;
            if(g[tx][ty]>h)
            high++;
            else if(g[tx][ty]<h)
            low++;
            else if(!st[tx][ty])
            {
                st[tx][ty]=true;
                q.push({tx,ty});
            }
        }

    }
    if(!high)
    res++;
    if(!low)
    cnt++;
}

int main(void)
{
    cin>>n;
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      cin>>g[i][j];
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
     if(!st[i][j])
     bfs(i,j);
    cout<<res<<" "<<cnt;
}
好的,根据上下文信息,这里是一个无向图的邻接矩阵存储方式的BFS遍历算法。下面是完整的代码: ```c++ #include <iostream> #include <queue> #include <cstring> using namespace std; const int MAXN = 100; int visited[MAXN]; // 标记数组,记录每个顶点是否已被访问 typedef struct { int v1, v2; } Bian; // 边结构体 typedef struct { int arcs[MAXN][MAXN]; // 存储邻接矩阵 int vexnum, arcnum; // 结点数和边数 } AMGraph; // 图结构体 void createGraph(AMGraph &G, Bian bian[], int n, int m) { // 建立无向图的邻接矩阵存储 int a, b; G.vexnum = n; G.arcnum = m; memset(G.arcs, 0, sizeof(G.arcs)); // 初始化邻接矩阵 for (int i = 0; i < G.arcnum; i++) { a = bian[i].v1; b = bian[i].v2; G.arcs[a][b] = G.arcs[b][a] = 1; // 无向图,边是双向的 } } void BFS(AMGraph G, int v, int Bf[]) { // 广度优先搜索 queue<int> Q; int I = 0, u; memset(visited, 0, sizeof(visited)); // 初始化visited数组 visited[v] = 1; Bf[I++] = v; Q.push(v); while (!Q.empty()) { u = Q.front(); Q.pop(); for (int i = 0; i < G.vexnum; i++) { if (G.arcs[u][i] && !visited[i]) { // 如果u和v之间有边,且v未被访问过 visited[i] = 1; Bf[I++] = i; Q.push(i); } } } } int main() { int n, m; // n为结点数,m为边数 cin >> n >> m; Bian bian[m]; int v; // 广搜起点 cin >> v; int Bf[MAXN]; // 广搜序列 for (int i = 0; i < m; i++) { cin >> bian[i].v1 >> bian[i].v2; } AMGraph G; createGraph(G, bian, n, m); // 建立图 BFS(G, v, Bf); for (int i = 0; i < n; i++) { cout << Bf[i] << " "; } cout << endl; return 0; } ``` 在该程序中,我们新加了一个结构体Bian,用于存储边的信息。在createGraph函数中,我们将边数组bian作为参数传入,遍历边数组,将每条边的两个顶点在邻接矩阵中标记为有边相连。最后,在主函数中输入结点数、边数、边的信息和广搜起点,建立图后调用BFS函数进行广搜遍历,并输出广搜序列。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值