zoukankan      html  css  js  c++  java
  • [noip模拟]B<构造>

    【题目描述】

    在两个n*m的网格上染色,每个网格中被染色的格子必须是一个四联通块(没有任何格子被染色也可以),四联通块是指所有染了色的格子可以通过网格的边联通,现在给出哪些格子在两个网格上都被染色了,保证网格的最外围一层不会在两个网格中同时被染色,即所有处于第x行第y列满足x=1或x=n或y=1或y=m的格子不会被在两个网格中同时被染色,请求出任意一种染色的方案,如果无解,请输出-1。

    输入格式

    第一行两个整数n,m

    接下来一个n*m的01矩阵,共n行,每行m个数字,每个数字之间无空格,0表示没有同时被染色,1表示在两个网格中同时被染色。

    输出格式

    如果有解,则输出两个n*m的01矩阵,分别表示两个矩阵的染色情况,数字之间无空格,两个矩阵之间有一行空行

    如果无解输出一行一个-1

    样例输入

    5 5

    00000

    01010

    00000

    01010

    00000

    样例输出

    00000

    01110

    00010

    01110

    00000

     

    01110

    01010

    01000

    01010

    01110

    样例解释

              

       第一个网格的染色       第二个网格的染色       紫色为在两个网格都染色的部分

    (蓝色部分为四联通块) (红色部分为四联通块)

     

    数据范围

    对于20%的数据,n*m<=12

    对于另外30%的数据,保证在两个矩阵都被染色的位置也是一个四联通块

    对于100%的数据,n,m<=500

     

     

    【思路】

    这个题的题意有点皮,要多读几次才理解(当然大佬都是一看就懂QAQ)

    20%的数据之间暴力就行,另外30%的数据其实直接输出你输入的矩阵两次就行

    100%的数据的做法是玄学,大佬们管着叫构造(原谅我学识短不知道QAQ,我还以为是反向的模拟)

    正解:

    直接构造答案两个图的模版,构造的要求是两个图模板互不重合,但是能和除开边界的所有的格子相邻(因为重合点是不会出现在边界)

    然后就可以开始愉快的构造了

    这个构造首先是边界一圈两个图各分一半,然后内部二分给两家,保证一个图和另一个图除开边界的点相邻

    然后无论重合点在哪都可以满足

    构造的方式很多种,我举一个我自己的例子

    橙色为答案图1,紫色为答案图2

    然后你可以随意在非边界格子里选几个作为重合格子,只需要在这两张图中将重复格子赋值为1输出就行

    答案初始图(以图片为例子)

    11111 0          000001

    101010          010101

    101010          010101

    101010          010101

    101010          010101

    100000          111110

    然后假如我们输入的是

    000000

    010010

    000000

    010010

    000000

    000000

    所以只需要在对应的初始图的点上赋值为1,然后输出图就行

    输出:

    11111 0          000001

    111010          010111

    101010          010101

    111010          010111

    101010          010101

    100000          111110

    我把重合点用红色写

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cmath>
     5 #include<queue>
     6 #include<algorithm>
     7 #include<cstdlib>
     8 #define maxn 505
     9 using namespace std;
    10 
    11 int n,m;
    12 int ans1[maxn][maxn];
    13 int ans2[maxn][maxn];
    14 
    15 int read(){
    16     int x=0,f=1;char ch=getchar();
    17     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    18     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 
    22 void init(){
    23     n=read();m=read();
    24     for(int i=1;i<=n;i++)
    25         for(int j=1;j<=m;j++)ans1[i][j]=1;
    26     for(int i=1;i<=n;i++)ans1[i][m]=0,ans2[i][m]=1;
    27     for(int i=2;i<=n;i++)
    28         for(int j=2;j<=m;j+=2)
    29             ans1[i][j]=0,ans2[i][j]=1;
    30     for(int i=2;i<=m;i++)ans1[n][i]=0,ans2[n][i]=1;    
    31 }
    32 
    33 void show(){
    34     for(int i=1;i<=n;i++){
    35         for(int j=1;j<=m;j++){
    36             printf("%d",ans1[i][j]);
    37         }printf("
    ");
    38     }
    39     printf("
    ");
    40     for(int i=1;i<=n;i++){
    41         for(int j=1;j<=m;j++){
    42             printf("%d",ans2[i][j]);
    43         }printf("
    ");
    44     }
    45 }
    46 
    47 void input(){
    48     char ch=getchar();
    49     for(int i=1;i<=n;i++){
    50         int j=1;
    51         while(ch<'0'||ch>'1'){ch=getchar();}
    52         while(ch>='0'&&ch<='1'){
    53             if(ch=='1')
    54                 ans1[i][j]=1,ans2[i][j]=1;
    55             ch=getchar();j++;}
    56     }
    57 }
    58 
    59 int main(){
    60     init();
    61     input();    
    62     show();
    63 }
    View Code

    【总结】

    构造很奇妙,需要脑回路清奇

     

  • 相关阅读:
    hdu 3996
    poj 3189
    poj 2391
    zoj 3165
    【Visual Studio】
    httpwebrequest Winform 上传图片
    [MVC] win7 下 配置 IIS 问题
    win7 下 升级 vs2008
    [Visual Studio 2010] NET 4.0 WinForm无法引用System.Web.dll的解决方法
    [XML] XML
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7744562.html
Copyright © 2011-2022 走看看