首页 > 其他分享 >洪水填充

洪水填充

时间:2023-08-02 19:23:03浏览次数:37  
标签:填充 洪水 long st int && include

洪水填充

洪水填充是搜索的一个简单应用。一张图上有多个区域,不同的区域用不同颜色区分,同一个区域的所有点的颜色都是相同的。给定图上的一个点,称为种子点,然后从种子点出发,把种子点所属的封闭区域用新颜色填充,这就是洪水填充。

洪水填充的编程用BFS和DFS都可以。洪水扩散过程符合BFS的原理,不过用DFS编码更简单。

例题

[hdu-1312](问题 - 1312 (hdu.edu.cn))

image-20230731180003502

代码模板

//#include <bits/stdc++.h>
#include <iostream>
#include <string.h>
using namespace std;
#define LL long long
const int N=30;
char a[N][N];
int n,m;
int st[N][N];
int sum;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

void dfs(int x,int y)
{
    int dx,dy;
    for(int i=0;i<4;i++)
    {
        dx=x+d[i][0];
        dy=y+d[i][1];
        if(dx>=0&&dx<m&&dy>=0&&dy<n&&st[dx][dy]==0&&a[dx][dy]=='.')
        {
            sum++;
            st[dx][dy]=1;
            dfs(dx,dy);
        }
    }
}

int main(){
    while(cin>>n>>m)
    {
        sum=0;
        memset(st,0,sizeof st);
        for(int i=0;i<m;i++)cin>>a[i];
        for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
        {
            if(a[i][j]=='@')
            {
                sum++;
                dfs(i,j);
                cout<<sum<<endl;
                break;
            }
        }
    }
    return 0;
}

[poj-2227](2227 -- The Wedding Juicer (poj.org))

image-20230731192843120

思路:通过"四周堵中央"的思路。从最外围的一圈开始找最小的位置,进行bfs搜索如果搜索到的位置的值小于该位置的值,把两者的差值记录,在把搜索到的值变为该位置的值,如果大于则不变。

代码模板

//#include <bits/stdc++.h>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
#define LL long long
#define x first
#define y second
typedef pair<int,int> PII;
const int N=310;
int a[N][N],st[N][N];
int n,m;
int sum;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct Node
{
    int x,y;
    int w;
    bool operator< (const Node &W)const
    {
        return w>W.w;
    }
}nd[N];

priority_queue<Node> q;

void bfs()
{
    int tx,ty;
    while(!q.empty())
    {
        Node t=q.top();
        q.pop();
        tx=t.x;
        ty=t.y;
        for(int i=0;i<4;i++)
        {
            int dx,dy;
            dx=tx+d[i][0];
            dy=ty+d[i][1];
            if(dx>0&&dx<=m&&dy>0&&dy<=n&&st[dx][dy]==0)
            {
                st[dx][dy]=1;
                Node tt;
                tt.x=dx,tt.y=dy,tt.w=a[dx][dy];
                if(t.w>tt.w)sum+=t.w-tt.w,tt.w=t.w;
                q.push(tt);
            }
        }
    }

}

int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    for(int j=1;j<=n;j++)
    {
        cin>>a[i][j];
        if(i==1||j==1||i==m||j==n)
        {
            Node t;
            st[i][j]=1;
            t.x=i;
            t.y=j;
            t.w=a[i][j];
            q.push(t);
        }
    }
    bfs();
    cout<<sum;
    return 0;

}

[lg-1514]([P1514 NOIP2010 提高组] 引水入城 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))

image-20230802185922366

思路:对第一行每一个点进行dfs,得到每一个点在最后一行所能覆盖的线段,对每段线段求最大值,通过标记函数可以判断最后一行是否都搜索过。对于得到的线段具有连续性,因为如果不是连续,我么们可以很容易的证明这个点无法到达(它所在联通块边界一定高于相邻点)

代码模板

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N=510;
int a[N][N],l[N][N],r[N][N];
int st[N][N];
int  n,m;
int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

void dfs(int x,int y)
{
    st[x][y]=1;
    int dx,dy;
    for(int i=0;i<4;i++)
    {
        dx=x+d[i][0];
        dy=y+d[i][1];
        if(dx>0&&dx<=n&&dy>0&&dy<=m&&a[dx][dy]<a[x][y])
        {
            if(!st[dx][dy])
            dfs(dx,dy);
            l[x][y]=min(l[x][y],l[dx][dy]);
            r[x][y]=max(r[x][y],r[dx][dy]);
        }
    }
}
int main(){
    cin>>n>>m;
    memset(l,0x3f,sizeof l);
    for(int i=1;i<=m;i++)
    l[n][i]=r[n][i]=i;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        cin>>a[i][j];
    }
    for(int i=1;i<=m;i++)
    if(!st[1][i])dfs(1,i);
    int cnt=0;
    bool flag=false;
    for(int i=1;i<=m;i++)
    if(!st[n][i])
    {
        flag=true;
        cnt++;
    }
    if(flag)
    {
        cout<<0<<endl<<cnt;
        return 0;
    }
    int left=1;
    while(left<=m)
    {
        int maxi=0;
        for(int i=1;i<=m;i++)
        if(l[1][i]<=left)
        maxi=max(maxi,r[1][i]);
        cnt++;
        left=maxi+1;
    }
    cout<<1<<endl<<cnt;
    return 0;
}

练习

hdu:5319/4574/1240/6113

洛谷:1506/1162/1649

poj:1979/3026/2157

声明

本文是《算法竞赛》的笔记,仅此而已。

标签:填充,洪水,long,st,int,&&,include
From: https://www.cnblogs.com/ckeri/p/17601554.html

相关文章

  • JAVA实现海报背景填充qrCode
    packagecom.open.openbank.qrCode;importjavax.imageio.ImageIO;importjava.awt.*;importjava.awt.geom.RoundRectangle2D;importjava.awt.image.BufferedImage;importjava.io.File;importjava.io.IOException;/***生成海报*/publicclassPosterTest{......
  • 公共字段自动填充--AOP
    自定义AutoFill注解,用于标识需要进行公共字段自动填充的方法/*自定义注解,用于标识某个方法需要进行功能字段自动填充处理*/@Target(ElementType.METHOD)//证明这个注解只能加在方法上@Retention(RetentionPolicy.RUNTIME)//固定的写法public@interfaceAutoFill{//指......
  • 6.3 填充和步幅
    填充 当卷积核的高度和宽度大于1时,卷积操作的输出的图像尺寸会变小,特别是在连续的多层卷积后,输出变得越来越小。这样一来,原始图像的边界丢失了许多有用的信息。填充是解决这个问题的一种办法,即,在输入图像的边界填充元素,通常是0.    通常,如果我们添加p<sub>h</sub>行填充......
  • 莆田洪水预警APP隐私声明
    本软件尊重并保护所有使用服务用户的个人隐私权。为了给您提供更准确、更有个性化的服务,本软件会按照本隐私权政策的规定使用和披露您的个人信息。但本软件将以高度的勤勉、审慎义务对待这些信息。除本隐私权政策另有规定外,在征得您的同意前,本软件不会将这些信息向其他人或向第三......
  • 莆田洪水预警APP技术支持
    iOS技术支持网址如果您在使用我们的产品时遇到任何问题,请随时与我们联系,我们将全意为您解决。请发送邮箱与我们联系,我们24小时为您服务。邮箱:[email protected]:251893507谢谢!IOSsupportswebaddressesIfyouencounteranyproblemwhenusingourproducts,pleasefeel......
  • 递归实现对TreeView的Node的填充
    树的数据结构是从根节点开枝散叶,父节点唯一。首先初始化要展示的数据,用Dictionary保存:Dictionary<int,List<int>>dt;初始化数据,数字0为根节点,字典中的key有[0,1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44]:privatevoidInitData(){dt=newDiction......
  • MyBatisPlus公共字段自动填充
    公共字段自动填充公共字段新增员工,修改、编辑员工信息时,都需要设置创建时间,修改时间等操作,这些操作过于重复、繁琐,为了有更快捷高效的,MyBatisPlus提供了公共字段自动填充功能,当我们执行insert和update操作时才执行MyBatisPLus公共字段自动填充就是在插入或者修改操作时,为指定字......
  • java aspose填充数据word生成pdf
    使用AsposeJava填充数据并生成PDF作为一名经验丰富的开发者,你可以通过以下步骤教导刚入行的小白如何使用AsposeJava库来填充数据并生成PDF。下面是整个过程的流程图:步骤描述1加载Word文档模板2创建Document对象3获取Document对象的MailMerge属性4创建包......
  • 关于 Spartacus ProdutList Component Service model$ 的填充逻辑
    源代码:这段代码是Angular中的RxJS代码,主要是创建一个名为model$的Observable对象,这个对象的生成逻辑复杂一些,主要涉及using,subscribe,pipe,shareReplay等函数的使用。逐行解释如下:readonlymodel$:Observable<ProductSearchPage>=using(这一行定义了一个......
  • Excel-批量填充数字
    1、一般情况下,都是使用鼠标左右键拖动来实现数据的填充的2、但是填充1200列,下拉拖动就非常麻烦,可以首先定位到A200。在屏幕左侧中央处找到剪切板下方的“A1”字样,鼠标单击A1文字,输入想要跳转的单元格,如A200,输入完成之后,点击回车即可。3、将要填充数据的单元格全部选中,选择的......