Flood Fill(一)

简介: 复习acwing算法提高课的内容,本篇为讲解算法:Flood Fill,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。

文章目录

前言

一、Flood Fill

二、例题,代码

AcWing 1097. 池塘计数

本题分析

AC代码

AcWing 1098. 城堡问题

本题分析

AC代码

AcWing 1106. 山峰和山谷

本题分析

AC代码

三、时间复杂度


前言

复习acwing算法提高课的内容,本篇为讲解算法:Flood Fill,关于时间复杂度:目前博主不太会计算,先鸽了,日后一定补上。


一、Flood Fill

Flood Fill算法是搜索的算法中的一种,用来解决类似田地覆盖这么一系列问题,算法核心是BFS


二、例题,代码

AcWing 1097. 池塘计数

本题链接:AcWing 1097. 池塘计数

本博客提供本题截图:

image.png

image.png

本题分析

本题就是水的覆盖问题,可以用bfs去解,核心思路就是从第一行第一列(即图中的第一个元素)去遍历,这里需要一个bool st[N][N]数组去记录这个点有没有被遍历过,如果被遍历过的话直接跳过这个点就可以了,我们每次挑选合适的点放入到队列之中,并用这个点作为“母点”去向8个方向去扩散,这里扩散的时候没有使用向量的方法,对于四扩散向量的方法很简单,但是对于8个方向的扩散,显然这里用一个二重for循环可以比较容易的解决问题,注意特判for循环中的条件,对于不符合条件的点continue

if (t.x == i && t.y == j) continue;      //遍历到这个点的时候continue
if (i < 0 || i >= n || j < 0 || j >= m) continue; //越界的时候continue
if (g[i][j] == '.' || st[i][j]) continue;   //这个点如果不是水的话或者这个点之前被遍历过的话就continue

这样三个if判断之后的点一定是符合题意可以扩散水的点,那么就把这个点放到队列中,并把这个点的bool值变成true

q[++ tt] = {i, j};
st[i][j] = true;

AC代码

#include <cstdio>
#include <algorithm>
#include <map>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010, M = N * N;
PII q[M];
char g[N][N];
bool st[N][N];
int n, m, cnt;
void bfs(int x1, int y1)
{
    int hh = 0, tt = 0;
    q[0] = {x1, y1};
    st[x1][y1] = true;
    while (hh <= tt)
    {
        auto 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 (t.x == i && t.y == j) continue;
                if (i < 0 || i >= n || j < 0 || j >= m) continue;
                if (g[i][j] == '.' || st[i][j]) continue;
                q[++ tt] = {i, j};
                st[i][j] = true;
            }
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
    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;
}

AcWing 1098. 城堡问题

本题链接:AcWing 1098. 城堡问题

本博客提供本题截图:

image.png

image.png

本题分析

和上一个题目基本一致,不同的有两点,一点是上一个题是八扩散,用的是两重for循环,这个题是四扩散,用的是向量,第二个不同是如何把数字形象化:位运算。

AC代码

#include <cstdio>
#include <map>
#include <algorithm>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 55, M = N * N;
PII q[M];
int g[N][N];
bool st[N][N];
int n, m;
int bfs(int x1, int y1)
{
    int area = 0;
    int dx[4] = {0, -1, 0, 1}, dy[4] = {-1, 0, 1, 0};
    int hh = 0, tt = 0;
    q[0] = {x1, y1};
    st[x1][y1] = true;
    while (hh <= tt)
    {
        auto t = q[hh ++];
        area ++;
        for (int i = 0; i < 4; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if (a < 0 || a >= n || b < 0 || b >= m) continue;
            if (g[t.x][t.y] >> i & 1) continue;
            if (st[a][b]) continue;
            q[++ tt] = {a, b};
            st[a][b] = true;
        }
    }
    return area;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) 
        for (int j = 0; j < m ; j ++ )
            scanf("%d", &g[i][j]);
    int cnt = 0, area = 0;
    for (int i = 0; i < n; i ++ ) 
        for (int j = 0; j < m; j ++ )
            if (!st[i][j])
            {
                cnt ++;
                area = max (area, bfs(i, j));
            }
    printf("%d\n%d\n", cnt, area);
    return 0;
}


目录
相关文章
|
13天前
|
6月前
|
C++
10 bfs(flood fill与最短路模型)
10 bfs(flood fill与最短路模型)
37 0
|
9月前
|
算法
frame_size (1536) was not respected for a non-last frame
frame_size (1536) was not respected for a non-last frame
61 0
frame_size (1536) was not respected for a non-last frame
|
程序员 iOS开发
frame 和 bounds的区别
frame 和 bounds的区别
104 0
frame 和 bounds的区别
Flood Fill(二)
AcWing 1106. 山峰和山谷
25 0
Flood Fill(二)
|
网络协议 安全 Linux
|
算法
PAT (Advanced Level) Practice - 1033 To Fill or Not to Fill(25 分)
PAT (Advanced Level) Practice - 1033 To Fill or Not to Fill(25 分)
69 0
|
存储 Java 索引
LeetCode 733: 图像渲染 flood-fill
题目: 有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。 An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535). 给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。
735 0
|
Android开发 开发者
Android官方dip值到pix值转换:dip2pix,dip2px,dp2px实现
Android官方的dip to pix,dip2pix,dp2px实现 网上流传的一个常用的把dip值转换为pix像素值的方法通常是这样的: public static int dip2px(Context co...
2901 0