填涂颜色问题该咋写啊

题目描述
由数字0 组成的方阵中,可能有若干任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。现要求把闭合圈内的所有空间都填写成2.例如:6X6的方阵(n=6),涂色前和涂色后的方阵如下:
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1
如果没有闭合圈,则涂色前后方阵相同。
输入格式:
每组测试数据第一行一个整数:n。其中n(1<=n<=30)
接下来n行,由0和1组成的nXn的方阵。
方阵内只有一个闭合圈,圈内至少有一个0。
输出格式:
已经填好数字2的完整方阵。
输入样例#1:
6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
输出样例#1:
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1
提示
1≤n≤30

填涂颜色问题该咋写啊

对于这种问题多多考虑搜索算法(例如DFS和BFS),利用他们来找到需要填充的区域,并将其标记为已经填充。具体来说,可以从给定的起点开始进行搜索,如果遇到了需要填充的区域,就将其标记为已经填充,并继续向周围的区域进行搜索,直到所有需要填充的区域都被找到并标记为已经填充为止。


#include<bits/stdc++.h>
using namespace std;
#define pi acos(-1)
#define mod 1000000007
#define ll long long
#define ull unsigned long long
#define mem(a) memset(a,0,sizeof(a))
#define cio ios::sync_with_stdio(false);
int next[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
int n;
int s[35][35];
int vis[35][35];
struct  node
{
    int x, y;
};
void bfs(int xx, int yy) //广搜连通块
{
    node q[10010];
    int head = 1;
    int tail = 1;
    q[tail].x = xx;
    q[tail].y = yy;
    tail++;
    vis[xx][yy] = 10;
    while(head<tail){
        for(int i = 0; i < 4; i++){
            int tx = q[head].x+next[i][0];
            int ty = q[head].y+next[i][1];
            if(tx<1||tx>n||ty<1||ty>n) continue;
            if(s[tx][ty]==0&&vis[tx][ty]==0){
                vis[tx][ty] = 10;
                q[tail].x = tx;
                q[tail].y = ty;
                tail++;
            }
        }
        head++;
    }
}
int jud()
{
    int flag = 1;
    //判断是否存在边界点(存在边界点即没有被1包围)
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(vis[i][j]==10){
                for(int k = 0; k < 4; k++){
                    int X = i+next[k][0];
                    int Y = j+next[k][1];
                    if(X<1||X>n||Y<1||Y>n) flag = 0;
                }
            }
        }
        if(flag==0) break;
    }
    if(flag==1){ //将封闭0改为2
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= n; j++){
                if(vis[i][j]==10){
                    s[i][j] = 2;
                }
            }
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(vis[i][j]==10) vis[i][j] = 5;
        }
    }
}
int main()
{
    cin >> n; //读入地图大小
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++) cin >> s[i][j]; //读入地图
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(s[i][j]==0&&vis[i][j]==0){ //判断是否已经为连通块
                bfs(i,j);//广搜连通块
                jud();//判断是否被1封闭
            }
        }
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(j!=1) cout << " ";
            cout << s[i][j];
        }
        cout << endl;
    }
    return 0;
}

https://blog.csdn.net/qq_45472594/article/details/106061310

扫描每一行,遇到第一个1后进入圈内,把遇到的0都赋值为2,遇到第二个1后出圈,遇到0不再赋值为2。需要考虑边界特殊情况。