Algorithm Notes

LJXin

记录算法刷题、竞赛思路与编程成长,希望每一篇都讲清楚一点、写扎实一点。

P1162 填涂颜色

P1162 填涂颜色

原题链接

解题思路

思想:与其找"圈内的0",不如先找"圈外的0",剩下未被访问的0就是圈内的

从所有边界上的 0 出发,BFS/DFS 标记所有"能到达边界的 0"

为什么从边界出发?

题目定义:无法到达边界的 0 = 圈内。那么反过来,能从边界 BFS 到的 0 = 圈外

扫描全图:
- 原来是 1 → 输出 1
- 是 0 且被标记(1所围成的圈外)→ 输出 0
- 是 0 且未被标记(圈内)→ 输出 2

代码实现


int grid[35][35];
int n;
bool vis[35][35];
int dx[] ={0,0,1,-1};
int dy[] ={-1,1,0,0};

void bfs(int x,int y){
    queue<pair<int,int>>q;
    q.push({x,y});
    vis[x][y] = true;
    while(!q.empty()){
        auto [x,y] = q.front();q.pop();
        rep(i,0,4){
            int nx=x+dx[i],ny=y+dy[i];
            if(nx<0||nx>=n||ny<0||ny>=n) continue;
            if(vis[nx][ny]||grid[nx][ny]==1) continue;
            vis[nx][ny]=true;
            q.push({nx,ny});
         }
    }
}
void solve(){
    cin>>n;
    rep(i,0,n)rep(j,0,n) cin>>grid[i][j];
    rep(i,0,n){
        if(!vis[i][0]&&grid[i][0]==0) bfs(i,0);
        if(!vis[i][n-1]&&grid[i][n-1]==0) bfs(i,n-1);
    }
    rep(i,0,n){
        if(!vis[0][i]&&grid[0][i]==0) bfs(0,i);
        if(!vis[n-1][i]&&grid[n-1][i]==0) bfs(n-1,i);
    }
    rep(i,0,n){
        rep(j,0,n){
        if(j) cout<<' ';
        
        if(grid[i][j]==1) cout<<1;
        else if(vis[i][j]) cout<<0;
        else cout<<2;
        }
        cout<<"\n";
    }

}

posted @ 2026-03-26 21:50  kliu_365  阅读(38)  评论(0)    收藏  举报
TOP