题目链接
链接: P1596 [USACO10OCT] Lake Counting S
题目描述
解题思路
本题我在acwing和洛谷上都看到了
做这道题首先要了解一下Flood Fill 算法(洪水填充算法)
作为一个广泛应用于计算机图形学和图像处理领域的经典算法,洪水填充算法(Flood Fill)在解决区域填充和区域标记等问题中具有重要地位。下面从算法原理、应用领域、实现方法和复杂度分析几个方面,介绍一下洪水填充算法。
算法原理
洪水填充算法的核心思想是从指定的种子点开始,向连通的方向进行“扩散”填充,直到满足某种特定条件或者不能继续填充为止。该算法通常使用深度优先搜索(DFS)或者广度优先搜索(BFS)来实现。在填充的过程中,需要考虑遍历的方向、种子点的选择、填充条件的判断等因素。
实现方法
洪水填充算法的一般实现方法包括:
- 递归实现:使用递归方式实现深度优先搜索,从种子点开始不断向相邻位置扩散。
- 队列实现:使用队列实现广度优先搜索,将种子点加入队列,依次取出队列中的点,并将其周围未填充的点加入队列。
复杂度分析
洪水填充算法的时间复杂度受填充区域的大小和形状影响,最坏情况下可达到 O(n * m),其中 n 和 m 分别表示区域的宽度和高度。空间复杂度取决于实现方式和填充区域的大小,递归实现通常需要考虑递归栈的空间占用,而队列实现则需要额外的空间来存储待扩散的点。
然后是这道题目的思路,这道题属于洪水填充算法的模板题,不是很难
这道题目的目标是统计一个矩阵中有多少个连通的地区,其中每个地区由字符 ‘W’ 表示。具体地,代码通过使用洪水填充算法(Flood Fill)来搜索连通的地区,并统计个数。
下面是这段代码的解题思路和总结:
-
理解题意和要求:首先需要理解题目要求,在这个问题中,我们需要统计一个矩阵中连通的地区的数量,其中连接由字符 ‘W’ 表示。通过理解题目要求,可以确定问题的目标和约束条件。
-
选择合适的算法:对于这个问题,由于需要统计连通的地区数量,并标记已经访问过的地区,可以选择使用洪水填充算法(Flood Fill)。
-
设计算法思路:在选择了洪水填充算法后,需要设计出基本的算法思路。代码中使用的
bfs
函数,通过广度优先搜索(BFS)的方式来实现洪水填充。具体来说,从每一个未被访问且为 ‘W’ 的位置开始,将其标记为已访问,然后将其周围未被访问且为 ‘W’ 的位置加入队列,直到队列为空。重复以上步骤,直到整个矩阵被遍历完,搜索到一个"W’点后,他的联通区域都的st数组 都会标记为false,所以有下面代码,所以每次搜索完,结果加一
if(!st[i][j]&&g[i][j]=='W')
{
bfs(i,j);
cnt++;
}
- 实现算法代码:将设计的算法思路转化为代码实现。代码中使用了队列来存储待访问的位置,使用一个二维数组
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算法(洪水填充算法)模板题目,很适合新手练习
通过本篇博客的学习,对洪水填充算法有了全面的认识和了解,同时也能够发现该算法在实际问题中的广泛应用。希望读者通过阅读本篇博客,能够充分领略到算法的重要性和实用性,将所学知识应用到实际工作中,取得更大的成就和进步。