cf1638 D. Big Brush

题意:

给定n×m网格,每个格子有一个正整数颜色。现在你要给一个n×m空白网格染色,每次可以把一个2×2区域染成某种颜色(会覆盖)。问用不超过nm次操作把空白网格图染成给定网格图的方案。

思路:

倒着来,每次染一个 “未染过色的格子均为同一颜色” 的2×2区域,看看周围的要不要入队

最后逆序输出

const signed N = 1e3 + 3;
int n, m, a[N][N];
queue<PII> q;
bool vq[N][N], v[N][N];
vector<tuple<int,int,int>> ans;

void color(int x, int y) {
    if(x < 1 || x >= n || y < 1 || y >= m) return;
    if(vq[x][y]) return; //进过队列

    int c = -1;
    for(int i = x; i <= x+1; i++)
        for(int j = y; j <= y+1; j++) {
            if(v[i][j]) continue;
            if(c == -1) c = a[i][j];
            else if(c != a[i][j]) return;
        }
    for(int i = x; i <= x+1; i++)
        for(int j = y; j <= y+1; j++)
            v[i][j] = 1;

    q.push({x,y}), vq[x][y] = 1;
    if(c != -1) ans.pb({x,y,c});
}

signed main() {
    iofast;
    cin >> n >> m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            cin >> a[i][j];

    for(int i = 1; i < n; i++)
        for(int j = 1; j < m; j++)
            color(i, j);
    while(q.size()) {
        auto [x,y] = q.front(); q.pop();
        for(int i = x-1; i <= x+1; i++)
            for(int j = y-1; j <= y+1; j++)
                color(i, j);
    }

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(!v[i][j]) return cout << -1, 0;

    reverse(all(ans));
    cout << ans.size() << endl;
    for(auto &[x,y,c] : ans)
        cout << x << ' ' << y << ' ' << c << endl;
}

posted @   Bellala  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示