1 条题解

  • 0
    @ 2025-12-21 9:38:56

    这是一道二维网格连通块计数问题,核心思路是用 DFS/BFS 遍历每个#组成的连通区域(有公共边的相邻#为同一连通块),统计连通块的数量。

    解题思路

    1. 问题转化:将“草丛”等价于#的连通块,问题转化为统计网格中#连通块的数量。
    2. 遍历网格:逐个检查每个格子,若遇到未访问过的#,则说明发现了一个新草丛,计数+1。
    3. 连通块遍历:用DFS/BFS遍历当前#所在的整个连通块,并标记所有格子为“已访问”,避免重复计数。

    C++ 代码实现(DFS版本)

    #include <iostream>
    #include <vector>
    using namespace std;
    
    // 深度优先搜索,遍历当前#的连通块并标记已访问
    void dfs(int x, int y, vector<string>& grid, vector<vector<bool>>& visited, int R, int C) {
        visited[x][y] = true;
        // 四个方向(上下左右)
        int dirs[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        for (int k = 0; k < 4; k++) {
            int nx = x + dirs[k][0];
            int ny = y + dirs[k][1];
            // 检查边界、是否为#、是否未访问
            if (nx >= 0 && nx < R && ny >= 0 && ny < C && grid[nx][ny] == '#' && !visited[nx][ny]) {
                dfs(nx, ny, grid, visited, R, C);
            }
        }
    }
    
    int main() {
        int R, C;
        cin >> R >> C;
        vector<string> grid(R); // 存储牧场地图
        for (int i = 0; i < R; i++) {
            cin >> grid[i];
        }
    
        vector<vector<bool>> visited(R, vector<bool>(C, false)); // 标记是否访问过
        int count = 0; // 草丛数量
    
        // 遍历每个格子
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                // 遇到未访问的#,说明是新草丛
                if (grid[i][j] == '#' && !visited[i][j]) {
                    count++;
                    dfs(i, j, grid, visited, R, C); // 遍历整个连通块
                }
            }
        }
    
        cout << count << endl;
        return 0;
    }
    

    代码说明

    1. 输入处理:读取牧场的行数R和列数C,再读取R行地图数据存入grid
    2. 访问标记:用visited二维数组标记每个格子是否被访问过,避免重复统计。
    3. DFS遍历
      • 当遇到未访问的#时,计数+1,并启动DFS。
      • DFS递归遍历当前#上下左右相邻格子,若相邻格子是未访问的#,则继续递归遍历,同时标记为已访问。
    4. 输出结果:最终count即为草丛的数量。

    信息

    ID
    5024
    时间
    10000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    8
    已通过
    4
    上传者