当前位置:首页 > 技术 > 正文内容

C++算法练习:孤岛面积计算与水域扩展问题解析

访客 技术 2026年6月25日 1

101. 孤岛面积统计

本题要求计算地图中所有与边界不相连的陆地总面积。初始思路误将孤岛定义为完全被海水包围的区域,实际应理解为未与地图边界接触的陆地区域。

在DFS实现中发现关键问题:当遍历四邻域时,若某次递归返回false需立即标记该区域非孤岛。改进后的逻辑如下:


bool dfs(int x, int y, vector& grid, vector& visited, int& area) {
    bool isIsolated = true;
    int m = grid.size(), n = grid[0].size();
    
    area++;
    if(x == 0 || x == m-1 || y == 0 || y == n-1) {
        isIsolated = false;
    }
    
    int directions[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    for(auto& dir : directions) {
        int nx = x + dir[0], ny = y + dir[1];
        if(nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
        if(grid[nx][ny] && !visited[nx][ny]) {
            visited[nx][ny] = true;
            if(!dfs(nx, ny, grid, visited, area)) {
                isIsolated = false;
            }
        }
    }
    return isIsolated;
}

优化后的主函数实现:


int main() {
    int rows, cols;
    cin >> rows >> cols;
    vector grid(cols, vector<int>(rows));
    for(int i=0; i> grid[j][i];
        }
    }
    
    vector visited(cols, vector<bool>(rows));
    int totalArea = 0;
    
    for(int i=0; i

102. 沉没孤岛问题

采用BFS策略实现水域扩展,核心思想是将非孤岛区域置零后重新统计。改进后的实现如下:


void bfs(queue>& q, vector& grid, vector& visited) {
    int m = grid.size(), n = grid[0].size();
    while(!q.empty()) {
        auto [x, y] = q.front(); q.pop();
        grid[x][y] = 0;
        
        int directions[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
        for(auto& dir : directions) {
            int nx = x + dir[0], ny = y + dir[1];
            if(nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
            if(grid[nx][ny] && !visited[nx][ny]) {
                visited[nx][ny] = true;
                q.push({nx, ny});
            }
        }
    }
}

主函数实现细节:


int main() {
    int rows, cols;
    cin >> rows >> cols;
    vector grid(rows, vector<int>(cols));
    for(int i=0; i> grid[i][j];
        }
    }
    
    vector visited(rows, vector<bool>(cols));
    queue> q;
    
    // 初始化边界队列
    for(int i=0; i

103. 水流路径问题

通过DFS实现水流路径检测,关键点在于维护两个布尔矩阵记录可达性。改进后的实现:


void dfs(vector& target, int x, int y, const vector& grid) {
    int m = grid.size(), n = grid[0].size();
    int directions[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    
    for(auto& dir : directions) {
        int nx = x + dir[0], ny = y + dir[1];
        if(nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
        if(grid[nx][ny] >= grid[x][y] && !target[nx][ny]) {
            target[nx][ny] = true;
            dfs(target, nx, ny, grid);
        }
    }
}

主函数实现细节:


int main() {
    int rows, cols;
    cin >> rows >> cols;
    vector grid(rows, vector<int>(cols));
    for(int i=0; i> grid[i][j];
        }
    }
    
    vector topleft(rows, vector<bool>(cols));
    vector botright(rows, vector<bool>(cols));
    
    // 初始化起点
    for(int i=0; i

104. 最大岛屿建造

通过DFS标记不同岛屿,并使用哈希集合记录已访问岛屿。关键实现细节:


void dfs(int mark, int x, int y, vector& grid, vector& visited, int& area) {
    grid[x][y] = mark;
    area++;
    int m = grid.size(), n = grid[0].size();
    
    int directions[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
    for(auto& dir : directions) {
        int nx = x + dir[0], ny = y + dir[1];
        if(nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
        if(grid[nx][ny] && !visited[nx][ny]) {
            visited[nx][ny] = true;
            dfs(mark, nx, ny, grid, visited, area);
        }
    }
}

主函数完整实现:


int main() {
    int rows, cols;
    cin >> rows >> cols;
    vector grid(rows, vector<int>(cols));
    bool allLand = true;
    
    for(int i=0; i> grid[i][j];
            if(grid[i][j] == 0) allLand = false;
        }
    }
    
    if(allLand) {
        cout << rows * cols;
        return 0;
    }
    
    vector visited(rows, vector<bool>(cols));
    vector<int> areas;
    int mark = 2;
    
    // 标记所有岛屿
    for(int i=0; i= 0 && nx < rows && ny >= 0 && ny < cols && 
                       grid[nx][ny] && used.find(grid[nx][ny]) == used.end()) {
                        current += areas[grid[nx][ny]-2];
                        used.insert(grid[nx][ny]);
                    }
                }
                
                maxArea = max(maxArea, current);
            }
        }
    }
    
    cout << maxArea + 1;
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。