P1596 [USACO10OCT] Lake Counting S——DFS、连通性问题

news/2025/2/22 12:14:26/文章来源:https://www.cnblogs.com/xiins/p/18730768

题目描述

Due to recent rains, water has pooled in various places in Farmer John's field, which is represented by a rectangle of N x M (1 <= N <= 100; 1 <= M <= 100) squares. Each square contains either water ('W') or dry land ('.'). Farmer John would like to figure out how many ponds have formed in his field. A pond is a connected set of squares with water in them, where a square is considered adjacent to all eight of its neighbors. Given a diagram of Farmer John's field, determine how many ponds he has.

输入格式

Line 1: Two space-separated integers: N and M * Lines 2..N+1: M characters per line representing one row of Farmer John's field. Each character is either 'W' or '.'. The characters do not have spaces between them.

输出格式

Line 1: The number of ponds in Farmer John's field.

输入输出样例 #1

输入 #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.

输出 #1

3

说明/提示

OUTPUT DETAILS: There are three ponds: one in the upper left, one in the lower left, and one along the right side.

题解

#include <iostream>
#include <vector>
using namespace std;const int MAXN = 105;
vector<string> field;
bool visited[MAXN][MAXN];
int n, m;// 八个方向的偏移量
int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};// 深度优先搜索函数,用于标记一个池塘的所有水
void dfs(int x, int y) {visited[x][y] = true;// 遍历八个方向for (int i = 0; i < 8; ++i) {int nx = x + dx[i];int ny = y + dy[i];// 检查新位置是否合法且为水且未被访问if (nx >= 0 && nx < n && ny >= 0 && ny < m && field[nx][ny] == 'W' && !visited[nx][ny]) {dfs(nx, ny);}}
}int main() {cin >> n >> m;field.resize(n);for (int i = 0; i < n; ++i) {cin >> field[i];}int pondCount = 0;// 初始化访问标记数组for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {visited[i][j] = false;}}// 遍历整个农田for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (field[i][j] == 'W' && !visited[i][j]) {dfs(i, j);pondCount++;}}}cout << pondCount << endl;return 0;
}

dfs(深度优先搜索)函数在这个问题中的主要作用之一就是标记与当前位置相连的所有水区域,避免重复计算,从而准确统计出池塘的数量。下面详细解释其具体作用:
当我们在遍历农田时,一旦发现一个未被访问过的水位置(字符为 'W'),就意味着可能找到了一个新的池塘的起始点。此时调用 dfs 函数,从这个起始点开始向其八个相邻方向进行深度优先搜索。
在搜索过程中,每到达一个合法的水位置(即该位置在农田范围内、是水且未被访问过),就将其标记为已访问(visited[x][y] = true)。通过递归地对相邻位置进行搜索,dfs 函数会不断深入探索,将与起始点相连的所有水位置都标记为已访问。
由于每个池塘是一个连通的水区域,在搜索过程中如果不进行标记,可能会多次访问同一个水位置,导致对同一个池塘进行重复计数。通过使用 visited 数组标记已访问的位置,当再次遇到这些位置时,就不会再次将其作为新池塘的起始点进行搜索,从而保证每个池塘只被统计一次。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/887971.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

充电桩功能扩展,解决桩企内存不足的问题

OCPP(开放充电点协议)1.6是电动汽车充电基础设施中广泛使用的通信标准。尽管OCPP 1.6为充电桩与中央管理系统(CSMS)之间的交互提供了基本功能,但由于OCPP主板的内存资源有限,其能够实现的功能也受到了一定的限制。为了解决这一问题,OCPP协议网关作为OCPP主板的扩展,能够…

Spring复习-AOP

AOP的概念 AOP,Aspect Oriented Programming,面向切面编程,是对面向对象编程OOP的升华。OOP是纵向对一个事物的抽象,一个对象包括静态的属性信息,包括动态的方法信息等。而AOP是横向的对不同事物的抽象,属性与属性、方法与方法、对象与对象都可以组成一个切面,而用这种思…

Univer sheet加载上下文菜单卡死崩溃问题定位

背景: 我的应用技术栈是Vue3,Univer是基于react的,所以定位问题花了很久,在此记录一下查问题的方式。 使用Chrome DevTools的Performance进行录制,复现卡死操作后,在Performance Monitr中可以看到CPU Usage持续100%,且页面重计算次数持续飙高。由于页面卡死,Performanc…

乐园杂音

沟槽的杉井光为什么还不填坑! 其实兔子最早看的一批轻小说就有乐杂,但是那时候没有写读后感的习惯,现在重刷一遍乐杂,就顺便写一下读后感。兔子每次给别人看这张图都会让他们猜女主是谁。 其实吧,虽然普遍认为《离别的钢琴奏鸣曲》比《乐园杂音》写的要好,但是兔子更喜欢…

一张图搞懂支付账务

会计与程序语言虽不同,却能从相同维度描绘业务场景。如何利用这一原理,拆解支付账务的科目设置、对账与核算流程,建立起清晰的账务处理逻辑?让我们一起一探究竟。学习账务的时候你是否经常有这些疑问“待结算和待清算是什么?为什么要有已清算?待结算和待清算是一回事吗?…

Diffusion-DPO:一种基于直接偏好优化的扩散模型对齐新方法

本文介绍了一种名为 Diffusion-DPO 的方法,该方法改编自最近提出的直接偏好优化 (DPO)。DPO 作为 RLHF 的简化替代方案,通过分类目标直接优化策略,以更好地满足人类偏好。诸如 GPT-4 和 Llama 2 等高性能大型语言模型 (LLM) 的训练通常分为两个阶段:https://avoid.overfit.…

联网搜索接口!大模型API和私有化部署联网搜索接口:基于互联网搜索服务的 API 接口技术分享与应用实践

联网搜索接口!大模型API和私有化部署联网搜索接口:基于互联网搜索服务的 API 接口技术分享与应用实践关键词:API 接口、互联网搜索、大模型、私有化部署、数据采集、技术分享、微信小程序、数字续坚、竞品对比一、引言在大模型 API 开发与私有化部署日益普及的背景下,如何在…

687. 最长同值路径(中)

目录题目题解:后序遍历 题目给定一个二叉树的 root ,返回 最长的路径的长度 ,这个路径中的 每个节点具有相同值 。 这条路径可以经过也可以不经过根节点。 两个节点之间的路径长度 由它们之间的边数表示。题解:后序遍历通过深度优先搜索后序遍历二叉树,计算并更新每个节点…

week 01 C语言基础

Week01 一.语言基础认知 1.1 C语言是什么? 通过一系列的语法和语义规则来描述计算机程序的行为和逻辑,可以将程序转化为二进制指令,并由CPU执行。 语言=语法+逻辑 1.2 C语言的特点简洁C语言的语法简单,简单明了,使得程序易于阅读和理解。高效C语言的执行效率高,可以用于开…

Qt布局之QSplitter

简述 QSplitter拆分器是一个布局控件。用户通过拖动它们之间的边界来控制子部件的大小。 在不确定子部件UI大小时,可以用此控件布局,让用户自行调整控件尺寸。 属性名称 类型 描述childrenCollapsible bool 用户是否可以将子部件的大小调整为0。默认情况下,子控件是可…

学习理论:预测器-拒绝器多分类弃权学习

弃权学习(learning with abstention)主要是为了使分类器在学习过程中可能出现的误导性或者不正确的信息时(这常被称为“幻觉”),能够对做出预测进行弃权。目前,弃权学习的方法主要可以分为以下几种:基于置信度的方法(confidence-based methods)。这种方法在预训练模型…

Cypher Chapter 6:DIGITAL CRYPTOGRAPHY

PUZZLE1 0110 0100 0110 0001 0111 0100 0110 0001SOLVE1 通过 ASCII 码表可知,明文为 data。 PUZZLE2 HELLO 0011 1111 0010 1010 0011 1110 0010 0000 0010 1011SOLVE2 容易猜出答案是 world,不过如何得到的呢? 考虑将 HELLO 换为 ASCII 码形式,即 0100 1000 0100 0101 0…