P1596 [USACO10OCT] Lake Counting S Flood Fill算法(洪水填充算法)

10 篇文章 0 订阅
6 篇文章 0 订阅


题目链接

链接: P1596 [USACO10OCT] Lake Counting S

题目描述

在这里插入图片描述

解题思路

本题我在acwing和洛谷上都看到了

做这道题首先要了解一下Flood Fill 算法(洪水填充算法)
作为一个广泛应用于计算机图形学和图像处理领域的经典算法,洪水填充算法(Flood Fill)在解决区域填充和区域标记等问题中具有重要地位。下面从算法原理、应用领域、实现方法和复杂度分析几个方面,介绍一下洪水填充算法。

算法原理

洪水填充算法的核心思想是从指定的种子点开始,向连通的方向进行“扩散”填充,直到满足某种特定条件或者不能继续填充为止。该算法通常使用深度优先搜索(DFS)或者广度优先搜索(BFS)来实现。在填充的过程中,需要考虑遍历的方向、种子点的选择、填充条件的判断等因素。

实现方法

洪水填充算法的一般实现方法包括:

  1. 递归实现:使用递归方式实现深度优先搜索,从种子点开始不断向相邻位置扩散。
  2. 队列实现:使用队列实现广度优先搜索,将种子点加入队列,依次取出队列中的点,并将其周围未填充的点加入队列。

复杂度分析

洪水填充算法的时间复杂度受填充区域的大小和形状影响,最坏情况下可达到 O(n * m),其中 n 和 m 分别表示区域的宽度和高度。空间复杂度取决于实现方式和填充区域的大小,递归实现通常需要考虑递归栈的空间占用,而队列实现则需要额外的空间来存储待扩散的点。

然后是这道题目的思路,这道题属于洪水填充算法的模板题,不是很难

这道题目的目标是统计一个矩阵中有多少个连通的地区,其中每个地区由字符 ‘W’ 表示。具体地,代码通过使用洪水填充算法(Flood Fill)来搜索连通的地区,并统计个数。

下面是这段代码的解题思路和总结:

  1. 理解题意和要求:首先需要理解题目要求,在这个问题中,我们需要统计一个矩阵中连通的地区的数量,其中连接由字符 ‘W’ 表示。通过理解题目要求,可以确定问题的目标和约束条件。

  2. 选择合适的算法:对于这个问题,由于需要统计连通的地区数量,并标记已经访问过的地区,可以选择使用洪水填充算法(Flood Fill)。

  3. 设计算法思路:在选择了洪水填充算法后,需要设计出基本的算法思路。代码中使用的 bfs 函数,通过广度优先搜索(BFS)的方式来实现洪水填充。具体来说,从每一个未被访问且为 ‘W’ 的位置开始,将其标记为已访问,然后将其周围未被访问且为 ‘W’ 的位置加入队列,直到队列为空。重复以上步骤,直到整个矩阵被遍历完,搜索到一个"W’点后,他的联通区域都的st数组 都会标记为false,所以有下面代码,所以每次搜索完,结果加一

if(!st[i][j]&&g[i][j]=='W')
          {
             bfs(i,j);
             cnt++;
          }
  1. 实现算法代码:将设计的算法思路转化为代码实现。代码中使用了队列来存储待访问的位置,使用一个二维数组 st 来记录已访问的位置。在主函数中,首先接收输入的矩阵大小和矩阵内容,然后调用 bfs 函数来统计连通的地区数量。

代码实现

#include <iostream>
#include <cstring>
#include <algorithm>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int N=1010,M=N*N;
int n,m;
bool st[N][N];
PII q[M];
char g[N][N];
void bfs(int sx,int sy)
{
    int hh=0,tt=0;

    q[0]={sx,sy};

    st[sx][sy]=true;
    while(hh<=tt)
    {
            PII t=q[hh++];
    for(int i=t.x-1;i<=t.x+1;i++)
     for(int j=t.y-1;j<=t.y+1;j++)
     {
         if(i<0||i>=n||j<0||j>=m) continue;
         if(st[i][j]||g[i][j]=='.') continue;
         if(t.x==i&&t.y==j) continue;

         st[i][j]=true;
         q[++tt]={i,j};
     }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) scanf("%s",g[i]);

    int cnt=0;

    for(int i=0;i<n;i++)
      for(int j=0;j<m;j++)
      {
          if(!st[i][j]&&g[i][j]=='W')
          {
             bfs(i,j);
             cnt++;
          }
      }
    printf("%d",cnt);
    return 0;
}

总结

Flood Fill算法(洪水填充算法)模板题目,很适合新手练习
通过本篇博客的学习,对洪水填充算法有了全面的认识和了解,同时也能够发现该算法在实际问题中的广泛应用。希望读者通过阅读本篇博客,能够充分领略到算法的重要性和实用性,将所学知识应用到实际工作中,取得更大的成就和进步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值