RCC 2017 Qual 1 Mail.Ru, April 2, 2017 Problem B. Painting the Wall

来源:互联网 发布:cf卡误删数据恢复 编辑:程序博客网 时间:2024/04/26 14:18

Problem B. Painting the Wall

题意:有一个n*m的墙,0为灯,不能涂颜料,1为瓷砖。问用k种颜色的颜料,使得连通的线段上没有重复的颜色。
(之前用了dfs,Wrong answer on test 2,不知道哪儿错了。因此借鉴了别人的思路)
思路:先构造出涂色方案。
比如n=4,m=5,k=3:
1 2 3 1 2
2 3 1 2 3
3 1 2 3 1
1 2 3 1 2
把灯的位置都换为0,然后检验有没有连续的超过k的线段,若没有,这就是一个可行解。

#include<cstdio>#include<cstring>using namespace std;int n,m,k;const int  maxn = 105;int g[maxn][maxn],s[maxn][maxn];void init()//预先构造出一个方案{    for(int i = 0; i < n; i++)    {        g[i][0] = i%k+1;        for(int j = 1; j < m; j++)            g[i][j] = (g[i][j-1])%k+1;    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d",&n,&m,&k);        init();        for(int i = 0; i < n; i++)        for(int j = 0; j < m; j++){            scanf("%d",&s[i][j]);            if(!s[i][j]) g[i][j] = 0;//如果是灯,就换成0        }        bool flag = 1;        //判断一行是否有超过k个的连通块        for(int i = 0; i < n; i++)        for(int j = 0; j < m; j++){            int cnt = 0;            while(j < m && s[i][j]) cnt++,j++;            if(cnt > k){                flag = 0;                break;            }        }        //判断一列是否有超过k个的连通块        for(int j = 0; j < m; j++)        for(int i = 0; i < n; i++){            int cnt = 0;            while(i < n && s[i][j]) cnt++,i++;            if(cnt > k){                flag = 0;                break;            }        }        if(!flag) printf("NO\n");        else{            printf("YES\n");            for(int i = 0; i < n; i++){                for(int j = 0; j < m-1; j++) printf("%d ",g[i][j]);                printf("%d\n",g[i][m-1]);            }        }    }    return 0;}
0 0
原创粉丝点击