【算法打卡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;

}
相关推荐
CoovallyAIHub1 小时前
Moonshine:比 Whisper 快 100 倍的端侧语音识别神器,Star 6.6K!
深度学习·算法·计算机视觉
CoovallyAIHub2 小时前
速度暴涨10倍、成本暴降6倍!Mercury 2用扩散取代自回归,重新定义LLM推理速度
深度学习·算法·计算机视觉
CoovallyAIHub2 小时前
实时视觉AI智能体框架来了!Vision Agents 狂揽7K Star,延迟低至30ms,YOLO+Gemini实时联动!
算法·架构·github
CoovallyAIHub3 小时前
开源:YOLO最强对手?D-FINE目标检测与实例分割框架深度解析
人工智能·算法·github
CoovallyAIHub3 小时前
OpenClaw:从“19万星标”到“行业封杀”,这只“赛博龙虾”究竟触动了谁的神经?
算法·架构·github
刀法如飞3 小时前
程序员必须知道的核心算法思想
算法·编程开发·算法思想
徐小夕5 小时前
pxcharts Ultra V2.3更新:多维表一键导出 PDF,渲染兼容性拉满!
vue.js·算法·github
CoovallyAIHub6 小时前
OpenClaw一脚踩碎传统CV?机器终于不再只是看世界
深度学习·算法·计算机视觉
CoovallyAIHub6 小时前
仅凭单目相机实现3D锥桶定位?UNet-RKNet破解自动驾驶锥桶检测难题
深度学习·算法·计算机视觉
zone77396 小时前
002:RAG 入门-LangChain 读取文本
后端·算法·面试