当前位置: 首页 > article >正文

(算法竞赛)DFS深搜3——数池塘问题解析与代码实现

题目描述

农夫约翰的农场可以表示成 N×M 个方格组成的矩形。由于近日的降雨,在约翰农场上的不同地方形成了池塘。每一个方格或者有积水(W),或者没有积水(.)。

农夫约翰打算数出他的农场上共形成了多少池塘。一个池塘是一系列相连的有积水的方格,每一个方格周围的四个方格都被认为是与这个方格相连的。现给出约翰农场的图样,要求输出农场上的池塘数。

输入
  • 第 1 行:由空格隔开的两个整数 N 和 M。

  • 第 2 到 N+1 行:每行 M 个字符代表约翰农场的一排方格的状态。每个字符或者是 W 或者是 .,字符之间没有空格。

数据范围
  • 1≤N,M≤100

输出

输出只有 1 行,输出约翰农场上的池塘数。

样例
输入
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
输出

13

来源

深搜 递归

问题分析
  1. 问题本质

    • 这是一个典型的连通块计数问题,可以通过深度优先搜索(DFS)或广度优先搜索(BFS)解决。

    • 每个连通的积水区域(池塘)可以通过搜索算法标记并计数。

  2. 关键点

    • 使用二维数组存储网格状态。

    • 使用一个访问标记数组(vis)记录每个格子是否被访问过,避免重复搜索。

    • 通过递归实现DFS,搜索每个积水格子的上下左右四个方向。

  3. 搜索方向

    • 定义方向数组 dxdy,分别表示四个方向(右、左、下、上)的行和列变化。

代码解析

以下是基于DFS的Python代码实现及其详细解析:

def dfs(xx, yy):
    """
    深度优先搜索函数,用于标记一个池塘中的所有积水格子。
    :param xx: 当前行
    :param yy: 当前列
    """
    vis[xx][yy] = 1  # 标记当前格子为已访问
    for i in range(4):  # 遍历四个方向
        x, y = xx + dx[i], yy + dy[i]  # 计算相邻格子的坐标
        # 检查是否在网格范围内、未访问且为积水格子
        if 0 <= x < n and 0 <= y < m and not vis[x][y] and a[x][y] == 'W':
            dfs(x, y)  # 递归搜索相邻格子

# 输入网格的行数和列数
n, m = map(int, input().split())
# 输入网格状态
a = [input() for _ in range(n)]
# 初始化访问标记数组
vis = [[0] * m for _ in range(n)]
# 定义方向数组
dx = [0, 0, 1, -1]  # 行变化(右、左、下、上)
dy = [1, -1, 0, 0]  # 列变化
# 初始化池塘计数
ans = 0

# 遍历每个格子
for i in range(n):
    for j in range(m):
        # 如果当前格子未访问且为积水格子
        if not vis[i][j] and a[i][j] == 'W':
            ans += 1  # 发现一个新池塘
            dfs(i, j)  # 标记整个池塘

# 输出池塘数量
print(ans)
代码运行逻辑
  1. 输入网格状态

    • 使用 input() 逐行读取网格状态,存储到二维列表 a 中。

  2. 初始化访问标记数组

    • 创建一个与网格大小相同的二维数组 vis,初始值为0,用于记录每个格子是否被访问过。

  3. DFS函数

    • 标记当前格子为已访问。

    • 遍历四个方向,计算相邻格子的坐标。

    • 如果相邻格子在网格范围内、未访问且为积水格子,则递归调用 dfs

  4. 遍历网格

    • 遍历每个格子,如果当前格子未访问且为积水格子,则发现一个新池塘,并调用 dfs 标记整个池塘。

  5. 输出结果

    • 输出池塘的总数。

运行结果示例

输入

10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.

输出

13

解释

  • 网格中共有13个连通的积水区域(池塘)。

  • 每个池塘通过DFS被标记并计数。

总结

这道题考察了深度优先搜索(DFS)的应用,适用于解决连通块计数问题。通过递归实现DFS,可以高效地标记每个池塘中的所有积水格子,并统计池塘的数量。希望这篇文章能帮助你更好地理解和解决类似问题。


http://www.kler.cn/a/514691.html

相关文章:

  • 第二届国赛铁三wp
  • 循环队列(C语言版)
  • 计算机毕业设计hadoop+spark股票基金推荐系统 股票基金预测系统 股票基金可视化系统 股票基金数据分析 股票基金大数据 股票基金爬虫
  • RV1126+FFMPEG推流项目源码
  • 变频器硬件接线
  • 基于Redis实现短信验证码登录
  • SPDK vhost介绍
  • 【2024年华为OD机试】 (E卷,100分) - 路灯照明问题(JavaScriptJava PythonC/C++)
  • 图像处理基础(4):高斯滤波器详解
  • Quick Startup,快捷处理自启程序的工具,加快电脑开机速度!
  • 基于STM32的智能书架管理系统设计
  • 【喜讯】海云安荣获“数字安全产业贡献奖”
  • 软件测试 —— 性能测试(jmeter)
  • llama 2代码详解
  • RK3568笔记七十六:使用V4L2框架录制MP4视频保存到本地
  • PAT甲级-1017 Queueing at Bank
  • 从入门到精通:RabbitMQ的深度探索与实战应用
  • 机器学习(4):决策树
  • Android实战经验篇-AndroidScrcpyClient投屏一
  • 使用docker打包部署jar包服务
  • 免费下载 | 2024中国智算中心产业发展白皮书
  • 【MySQL — 数据库基础】深入解析MySQL常用表操作
  • Servlet3 简单测试
  • 加强版第二十二章KTL光流法
  • priority_queue底层实现细节
  • 图片生成Prompt编写技巧