CFgym:Painting the Wall(BFS)

解决一个算法问题,关于如何用不同颜色绘制墙面的特定区域,确保相邻区域颜色不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

"B" Painting the Wall
Time limit 2 seconds
Memory limit 256 megabytes

Little girl Masha is looking at the wall in her room. The wall is tiled with square tiles, but some of the tiles are replaced with lamps. So it is possible to consider the wall to be a rectangle of n × m, some cells contain tiles, other cells contain lamps.

Masha has paints of k different colors. Consider continuous vertical or horizontal segments of tiles, having an edge of the wall or a lamp at each of its ends. Masha wants to paint all tiles in such way, that any such segment has all tiles painted in different colors. Masha will not paint lamps. She doesn't have to use all the colors.

Help Masha to paint the wall.

Input format

Input contains several test cases. The first line contains the number of test cases t.

Each test case is described by several lines. The first line contains three integers: nmk (1 ≤ n, m ≤ 100, 1 ≤ k ≤ max(n, m)) — the size of the wall and the number of paints Masha has.

The following n lines contain m integers aij each:

  • aij = 0 means that the position (i, j) contains the lamp;
  • aij = 1 means that the position (i, j) contains the tile.

The total number of tiles and lamps in all test cases of one input doesn't exceed 105.

Output format

For each test case first print the answer:

  • NO, if there is no way to paint the wall.
  • YES, if there is at least one way to paint the wall. In this case the following n lines must contain m integers bij each — the color of the tile at position (i, j), or 0, if there is a lamp at this position. If there are several ways to paint the wall, you can output any one.

Examples
Input data
2
4 3 2
0 1 0
1 0 1
1 0 1
0 1 0
3 4 2
0 1 0 1
1 0 1 1
1 1 1 0
Output data
YES
0 2 0 
2 0 2 
1 0 1 
0 1 0 
NO
题意:一个N*M的地图,k种颜料,地图0的地方不能涂,1的地方连成一条线段的部分不能涂上相同的颜色,输出上色后的地图。

思路:涂成形如

1 2 3 4 5

2 3 4 5 1

3 4 5 1 2

4 5 1 2 3

5 1 2 3 4这样就保证不会同一行和列出现相同,可以先涂满整个地图再把0位置的放回原位,或者老老实实地bfs。

# include <bits/stdc++.h>
using namespace std;
int vis[103][103], a[103][103];
int t, n, m, k;
int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};
struct node
{
    int x, y, col, dir;
}q[10003];
bool dfs(int x, int y, int pre, int d)
{
    if(x<0||y<0||x>=n||y>=m||a[x][y]==0) return true;
    if(d>k) {return false;}
    if(pre!=-1)
        return dfs(x+dx[pre], y+dy[pre],pre,d+1);
    for(int i=0; i<4; ++i)
    {
        int mx=x+dx[i], my=y+dy[i];
        if(!dfs(mx,my,i,d+1))
            return false;
    }
    return true;
}

void bfs(int x, int y)
{
    int l=0, r=0;
    q[r++] = node{x,y,0,-1};
    vis[x][y] = 1;
    a[x][y] = 0;
    while(l<r)
    {
        node u=q[l];
        ++l;
        for(int i=0; i<4; ++i)
        {
            int mx = u.x+dx[i], my=u.y+dy[i];
            if(mx<0||my<0||mx>=n||my>=m||a[mx][my]==0||vis[mx][my]) continue;
            vis[mx][my] = 1;
            int col;
            if(i==0||i==1) col=(u.col+1)%k;
            else col=(u.col+k-1)%k;
            q[r++] = node{mx,my,col};
            a[mx][my] = col;
        }
    }
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        bool flag = true;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0; i<n; ++i)
            for(int j=0; j<m; ++j)
            scanf("%d",&a[i][j]);
        memset(vis, 0, sizeof(vis));
        for(int i=0; i<n; ++i)
        {
            for(int j=0; j<m; ++j)
            {
                if(a[i][j]==0) continue;
                if(!dfs(i,j,-1,1))
                {
                    flag = false;
                    break;
                }
            }
            if(!flag) break;
        }
        if(!flag)
        {
            puts("NO");
            continue;
        }
        for(int i=0; i<n; ++i)
        {
            for(int j=0; j<m; ++j)
            {
                if(a[i][j]!=0&&!vis[i][j])
                {
                    bfs(i,j);
                }
            }
        }
        puts("YES");
        for(int i=0; i<n; ++i)
        {
            for(int j=0; j<m; ++j)
            {
                printf("%d%c",vis[i][j]?a[i][j]+1:0, j==m?'\n':' ');
            }
            puts("");
        }
    }
    return 0;
}
close



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值