一. 题目

image.png

二. 理论

  • Flood Fill 算法是一种经典的用于图形处理和游戏开发的算法,常用于对区域进行着色或标记,类似于图像编辑工具中的“油漆桶”工具。它通过递归或迭代的方式从给定的初始点开始,向四周扩展,填充与初始点相同颜色或值的区域,直到边界或遇到不同的颜色。

  • 基本思想

  • 【1】从一个初始像素点(或坐标)开始,检查它周围的相邻像素(上下左右或对角线)。

  • 【2】如果相邻像素的颜色与初始像素相同,则将它们染成目标颜色,并递归地继续检查它们的相邻像素。

  • 【3】直到没有更多的相邻像素符合条件时,填充操作完成。


  • 本题思路:利用FooldFill进行染色,同时在此过程中,利用二进制位数字判断是否存在墙。

三. 代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N=55;

int n, m;
int g[N][N];

class FloodFill
{
public://下标偏移量, 1表示西墙,2表示北墙,4表示东墙,8表示南墙, 偏移量对应墙
    int dx[4]={0, -1, 0, 1}, dy[4]={-1, 0, 1, 0};
    int bcnt, acnt, maxCnt;//队列索引和当前房间的数量, 房间数, 最大房间数量
    bool st[N][N];
public:
    void initIO()
    {
        // 关闭输入输出缓存,使效率提升
        ios::sync_with_stdio(false);
        // 解除cin和cout的默认绑定,来降低IO的负担使效率提升
        cin.tie(nullptr);
        cout.tie(nullptr);
    }

    FloodFill()
    {
        initIO();
        bcnt=0, acnt=0, maxCnt=0;
        fill(st[0], st[0]+N*N, false);
    }

    //遍历过的地方,都置为true
    void dfs(int x, int y)
    {
        ++bcnt, st[x][y]=true;
        for(int i=0;i<4;++i)
        {
            int a=x+dx[i], b=y+dy[i];
            if(a<0||a>=n||b<0||b>=m||st[a][b]||(g[x][y]>>i&1)) continue;
            dfs(a, b);
        }    
    }
}ff;

int main()
{
    cin>>n>>m;
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
            cin>>g[i][j];

    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j)
            if(!ff.st[i][j])//当没有被遍历过
            {
                ff.bcnt=0, ++ff.acnt;
                ff.dfs(i, j);
                ff.maxCnt=max(ff.maxCnt, ff.bcnt);
            }
    cout<<ff.acnt<<endl<<ff.maxCnt;
}