codeforces 297D Color the Carpet(构造)

D. Color the Carpet
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Even polar bears feel cold when lying on the ice. Therefore, a polar bear Alice is going to make a carpet. The carpet can be viewed as a grid with height h and width w. Then the grid is divided into h × w squares. Alice is going to assign one of k different colors to each square. The colors are numbered from 1 to k. She may choose not to use all of the colors.

However, there are some restrictions. For every two adjacent squares (squares that shares an edge) x and y, there is a color constraint in one of the forms:

  • color(x) = color(y), or
  • color(x) ≠ color(y).

Example of the color constraints:

Ideally, Alice wants to satisfy all color constraints. But again, life in the Arctic is hard. It is not always possible to satisfy all color constraints. Fortunately, she will still be happy if at least  of the color constraints are satisfied.

If she has 4 colors she can color the carpet in the following way:

And she is happy because  of the color constraints are satisfied, and . Your task is to help her color the carpet.

Input

The first line contains three integers h, w, k (2 ≤ h, w ≤ 1000, 1 ≤ k ≤ w·h).

The next 2h - 1 lines describe the color constraints from top to bottom, left to right. They contain w - 1, w, w - 1, w, ..., w - 1 characters respectively. Each color constraint is represented by a character "E" or "N", where "E" means " = " and "N" means " ≠ ".

The color constraints listed in the order they are depicted on the picture.

Output

If there is a coloring that satisfies at least  of the color constraints, print "YES" (without quotes) in the first line. In each of the next h lines, print w integers describing the coloring.

Otherwise, print "NO" (without quotes).

Examples
input
3 4 4
ENE
NNEE
NEE
ENEN
ENN
output
YES
1 1 2 2
3 4 1 1
3 3 2 4



题目大意:选取1-k 以内的数填入方格中,使满足的等号和不等号的个数>=3/4

 如果K 大于等于2的话,其实我们可以只用1,2 来填,因为他有列之间的关系矩阵,和行之间的关系矩阵,所以我们考虑先满足较大的矩阵关系,然后再去判段另一个矩阵的关系。如果某一列(或某一行,看是什么矩阵)满足条件的个数小于一半的话,就把这一列取反(1变2,2变1),因为关系是相对的,所以之前满足的矩阵依然满足。总之,挺麻烦的,一定要想清楚了再写。。。。

#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<cmath>  
#define N 2003  
using namespace std;  
int m,n,k;  
int a[N][N],b[N][N],cnta,cntb;  
int ans[N][N];  
int main()  
{  
    //freopen("a.in","r",stdin);
    scanf("%d%d%d",&n,&m,&k);  
    for (int i=1;i<=n+n-1;i++)  
     {  
        char s[1003]; scanf("%s",s+1);  
        if (i&1)  {  
            ++cnta;  
            for (int j=1;j<=m-1;j++)  
            if (s[j]=='N')  a[cnta][j]=1;  
        }  
        else{  
            ++cntb;  
            for (int j=1;j<=m;j++)  
             if (s[j]=='N')  b[cntb][j]=1;  
        }  
     }  
    /*for (int i=1;i<=n;i++)  
      {  
        for (int j=1;j<=m-1;j++)  
         cout<<a[i][j]<<" ";  
        cout<<endl;  
      }  
    for (int i=1;i<=n-1;i++)  
     {  
        for (int j=1;j<=m;j++)  
         cout<<b[i][j]<<" ";  
        cout<<endl;  
     } */
    if (k==1){  
        for (int i=1;i<=n;i++)  
         for (int j=1;j<=m;j++) ans[i][j]=1;  
        int t=0;  
        for (int i=1;i<=n;i++)  
         {  
            for (int j=2;j<=m;j++)  
             if((ans[i][j-1]^ans[i][j])==a[i][j-1]||((ans[i][j-1]^ans[i][j])!=0&&a[i][j-1]))  
              t++;  
         }  
        for (int i=1;i<=m;i++)  
        {  
            for (int j=2;j<=n;j++)  
            if ((ans[j-1][i]^ans[j][i])==b[j-1][i]||((ans[j-1][i]^ans[j][i])!=0&&b[j-1][i]))  
             t++;  
        }  
        if (4*t>3*(n*(m-1)+(n-1)*m))  {  
            printf("YES\n");  
            for (int i=1;i<=n;i++)  
            {  
                for (int j=1;j<=m;j++)  
                 if (!ans[i][j])  printf("2 ");  
                 else printf("%d ",ans[i][j]);  
                printf("\n");  
            }  
        }  
        else printf("NO\n");  
        return 0;  
    }  
    if (n*(m-1)<=(n-1)*m){  
        for (int i=1;i<=m;i++)  
         {  
            for (int j=1;j<=n;j++)  
             {  
                if (j==1)  ans[j][i]=1;  
                else if (!b[j-1][i])  ans[j][i]=ans[j-1][i];  
                     else ans[j][i]=ans[j-1][i]^1;  
             }  
         }  
        for (int i=2;i<=m;i++)  
         {  
            int t=0;  
            for (int j=1;j<=n;j++)  
             if((ans[j][i-1]^ans[j][i])==a[j][i-1]||((ans[j][i]^ans[j][i-1])!=0&&a[j][i-1]))  
              t++;  
            int mid=(n+1)/2;
            if (t<mid)   
             for (int j=1;j<=n;j++)  ans[j][i]=ans[j][i]^1;  
         }  
    }  
    else  
    {  
        for (int i=1;i<=n;i++)  
        {  
            for (int j=1;j<=m;j++)  
            {  
                if (j==1)  ans[i][j]=1;  
                else if (!a[i][j-1])  ans[i][j]=ans[i][j-1];  
                else ans[i][j]=ans[i][j-1]^1;  
            }  
        }  
        for (int i=2;i<=n;i++)  
        {  
            int t=0;  
            for (int j=1;j<=m;j++)  
            if ((ans[i][j]^ans[i-1][j])==b[i-1][j]||((ans[i][j]^ans[i-1][j])!=0&&b[i-1][j]))  
             t++;
			int mid=(m+1)/2;  
            if (t<mid)  
             for (int j=1;j<=m;j++)  ans[i][j]=ans[i][j]^1;  
        }  
    }  
    printf("YES\n");  
    for (int i=1;i<=n;i++)  
    {  
        for (int j=1;j<=m;j++)  
         if (!ans[i][j])  printf("2 ");  
         else printf("%d ",ans[i][j]);  
        printf("\n");  
    }  
}  


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值