【算法打卡day5 | 2026-02-10 周二 | 算法: BFS and BFS】7_卡码网103_高山流水

- 第 164 篇 -
Date: 2026 - 02- 10 (周二)
Author: 郑龙浩(仟墨)

2026-02-10 周二 | 算法打卡day5

文章目录

7_卡码网103_高山流水

**题目描述

现有一个 N × M 的矩阵,每个单元格包含一个数值,这个数值代表该位置的相对高度。矩阵的左边界和上边界被认为是第一组边界,而矩阵的右边界和下边界被视为第二组边界。

矩阵模拟了一个地形,当雨水落在上面时,水会根据地形的倾斜向低处流动,但只能从较高或等高的地点流向较低或等高并且相邻(上下左右方向)的地点。我们的目标是确定那些单元格,从这些单元格出发的水可以达到第一组边界和第二组边界。

输入描述

第一行包含两个整数 N 和 M,分别表示矩阵的行数和列数。

后续 N 行,每行包含 M 个整数,表示矩阵中的每个单元格的高度。

输出描述

输出共有多行,每行输出两个整数,用一个空格隔开,表示可达第一组边界和第二组边界的单元格的坐标,输出顺序任意。

输入示例

复制代码
5 5
1 3 1 2 4
1 2 1 3 2
2 4 7 2 1
4 5 6 1 1
1 4 1 2 1

输出示例

复制代码
0 4
1 3
2 2
3 0
3 1
3 2
4 0
4 1
cpp 复制代码
// Date: 2026-02-10 周一 Author:郑龙浩

// 7_卡码网103_高山流水_BFS_DFS

  

// 逆向思维思考:

// 也就是本身水是从中间向两边界流,现在是从两个边界往中间流,即从低往高流

// - 然后所有第一边界搜索的的坐标用first_visited数组去标记

// - 第二边界的用second_visited数组去标记

// 两者共同搜索过的坐标就是既可以到达第一也可以到到第二边界的坐标

  
  

// 方法1:DFS 方法2: BFS

#include "bits/stdc++.h"

using namespace std;

  

int direction[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

  

void dfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {

    if (visited[x][y] == true) { // 要先判断传入的坐标是否是被访问过的,以免出现问题

        return;

    }

    visited[x][y] = true; // 但凡传来的且没访问过的,都合格的,要标记访问过

    int height = grid.size();

    int width = grid[0].size();

    for (int i = 0; i < 4; i++) {

        int nextX = x + direction[i][0];

        int nextY = y + direction[i][1];

  

        // 只有 不越界 && 没访问过 && 下一个的坐标高度 > 当前坐标高度时,才会以下一个高度为中心搜索

        if (nextX >= 0 && nextX < height && nextY >=0 && nextY < width && visited[nextX][nextY] == false && grid[nextX][nextY] >= grid[x][y]) {

            dfs(grid, visited, nextX, nextY);

        }

    }

}

  

void bfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {

    if (visited[x][y] == true) {

        return;

    }

    queue <pair <int, int>> que; // 待搜索的加入到这里面来

    que.push({x, y});

  

    int height = grid.size();

    int width = grid[0].size();

    // 每次都以队列头为中心搜索四周,如果找到符合条件的,就将坐标加入到que待访问的队列

    while (!que.empty()) {

        pair <int, int> cur = que.front(); // 取出队列头

        que.pop(); // 只有取出队列的时候,才算访问过了

        visited[cur.first][cur.second] = true;

        for (int i = 0; i < 4; i++) {

            int nextX = cur.first + direction[i][0];

            int nextY = cur.second + direction[i][1];

  

            // 只有 不越界 && 没访问过 && 下一个的坐标高度 > 当前坐标高度时,才会加入que这个待搜索队列

            if (nextX >= 0 && nextX < height && nextY >=0 && nextY < width && visited[nextX][nextY] == false && grid[nextX][nextY] >= grid[cur.first][cur.second]) {

                que.push({nextX, nextY});

            }

        }

    }

}

  

int main(void) {

    ios::sync_with_stdio(0);

    cin.tie(0); cout.tie(0);

  

    int N, M; cin >> N >> M;

  

    vector <vector <int>> grid(N, vector <int> (M, 0));

    vector <vector <bool>> first_visited(N, vector <bool> (M, 0));

    vector <vector <bool>> second_visited(N, vector <bool> (M, 0));

  

    for (int i = 0; i < N; i++) {

        for (int j = 0; j < M; j++) {

            cin >> grid[i][j];

        }

    }

  

    // 处理左右两边(第一边界和第二边界)

    for (int i = 0; i < N; i++) {

        bfs(grid, first_visited, i, 0);

        bfs(grid, second_visited, i, M - 1);

    }

    // 处理上下两行(第一边界和第二边界)

    for (int i = 0; i < M; i++) {

        bfs(grid, first_visited, 0, i);

        bfs(grid, second_visited, N - 1, i);    

    }

  

    // 遍历每一个点,看是否能同时到达第一组边界和第二组边界

    for (int i = 0; i < N; i++) {

        for (int j = 0; j < M; j++) {

            if (first_visited[i][j] == true && second_visited[i][j] == true) {

                cout << i << ' ' << j << '\n';

            }

        }

    }

    return 0;

}
相关推荐
寻寻觅觅☆8 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
偷吃的耗子9 小时前
【CNN算法理解】:三、AlexNet 训练模块(附代码)
深度学习·算法·cnn
化学在逃硬闯CS9 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
ceclar12310 小时前
C++使用format
开发语言·c++·算法
Gofarlic_OMS10 小时前
科学计算领域MATLAB许可证管理工具对比推荐
运维·开发语言·算法·matlab·自动化
夏鹏今天学习了吗10 小时前
【LeetCode热题100(100/100)】数据流的中位数
算法·leetcode·职场和发展
忙什么果11 小时前
上位机、下位机、FPGA、算法放在哪层合适?
算法·fpga开发
董董灿是个攻城狮11 小时前
AI 视觉连载4:YUV 的图像表示
算法
ArturiaZ12 小时前
【day24】
c++·算法·图论
大江东去浪淘尽千古风流人物12 小时前
【SLAM】Hydra-Foundations 层次化空间感知:机器人如何像人类一样理解3D环境
深度学习·算法·3d·机器人·概率论·slam