• 【实验舱国庆营模拟】Day2 A.divide


    题目链接

    题意:

      对一个$n$行$m$列的网格黑白染色,满足:

      1.黑色的格子两两四联通,白色格子两两四联通,且黑色的格子经过旋转和平移可以和白色的格子重合

      2.$w(wx,wy)$这个格子是白色的,$b(bx,by)$这个格子是黑色的。

      要求找到任意一个解,或者判断无解。多组数据。

      $1le Tle 10^3, ;1le n,mle 50, ;1le wx,bxle n, ; 1le wy,byle m ,; (wx,wy) eq(bx,by)$

    分析:

      首先考虑什么时候无解。

      ①网格数为奇数,无法均分

      ②仅有单行/单列且指定黑白格在同侧,也无法均分

      接下来分类讨论:

      ①若$2|m$(可通过整张图旋转$90^{circ}$得到,下同),且两个指定点分居中线两侧,则直接对切。

     

      ②若指定点居于中线同侧,且在不同行,可如上图染色。

     

     

      ③若指定点居于中线异侧,且在相同行,离中线近的指定点不在最后一行,可如上图染色。

    实现(100分):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #define IL inline
    #define UI unsigned int
    #define RI register int
    using namespace std;
    const int N=50;
    
    IL void swap(int &x,int &y){
        int t=x;    x=y;    y=t;
    }
    
        int T,n,m,wx,wy,bx,by;
        bool flag1,flag2,flag3,flag4;
        int nn,mm,c,d,x[2],y[2];
        int bod[N+3][N+3];
    
    IL void step1(){
        if(n*m%2==1){
            flag1=true;    return ;        
        }
        
        x[0]=wx;    y[0]=wy;
        x[1]=bx;    y[1]=by;
        if(m%2==1){
            flag2=true;
            swap(n,m);
            for(int i=0;i<2;i++)
                swap(x[i],y[i]);
            
        }
        
        mm=m/2;
        if(n==1&&((y[0]<=mm&&y[1]<=mm)||(y[0]>mm&&y[1]>mm))){
            flag1=true;    return ;
        }
        
    }
    
    IL bool cmp1(){
        if(y[0]==y[1])
            return x[0]<x[1];
        return y[0]<y[1];
        
    }
    
    IL bool cmp2(){
        if(x[0]==x[1])
            return y[0]<y[1];
        return x[0]<x[1];
        
    }
    
    IL void sol1(){
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                bod[i][j]=(j<=mm)?c:d;
                
    }
    
    IL void sol2(){
        int vx[2];
        for(int i=0;i<2;i++)
            vx[i]=n-x[i];
            
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                bod[i][j]=(i<=(j<=mm?x[c]:vx[c]))?c:d;
                
    }
    
    IL void sol3(){
        int vx[2];
        for(int i=0;i<2;i++)
            vx[i]=n-x[i]+1;
            
        int vy[2];
        for(int i=0;i<2;i++)
            vy[i]=m-y[i]+1;
            
        memset(bod,-1,sizeof bod);
        for(int i=1;i<=x[d];i++)
            for(int j=y[d];j<=mm;j++)
                bod[i][j]=d;
                
        for(int i=vx[d];i<=n;i++)
            for(int j=mm+1;j<=vy[d];j++)
                bod[i][j]=c;
                
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            if(!~bod[i][j])
                bod[i][j]=(j<=mm)?c:d;
                
    }
    
    IL void step2(){
        c=cmp1()?0:1;    d=c^1;
        
        if(y[c]<=mm&&y[d]>mm){
            sol1();    return ;
        }
        
        if(y[c]>mm){
            flag3=true;
            for(int i=0;i<2;i++)
                y[i]=m-y[i]+1;
            
            c=cmp1()?0:1;    d=c^1;
            
        }
        
        if(x[d]==n){
            flag4=true;
            for(int i=0;i<2;i++)
                x[i]=n-x[i]+1;
                
        }
        
        c=cmp2()?0:1;    d=c^1;
        
        if(x[c]!=x[d])
            sol2();
        else 
            sol3();
        
    }
    
    IL void step3(){
        if(flag4)
            for(int i=1,ti=n;i<ti;i++,ti--)
                for(int j=1;j<=m;j++)
                    swap(bod[i][j],bod[ti][j]);
        
        if(flag3)
            for(int i=1;i<=n;i++)
                for(int j=1,tj=m;j<=mm;j++,tj--)
                    swap(bod[i][j],bod[i][tj]);
                    
        if(flag2){
            int tmp[N+3][N+3];
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    tmp[j][i]=bod[i][j];
            memcpy(bod,tmp,sizeof bod);
            swap(n,m);
            
        }
        
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++)
                printf("%d ",bod[i][j]);
            printf("
    ");
            
        }
        
    }
    
    int main(){
        freopen("A.in","r",stdin);
        freopen("A.out","w",stdout);
    
        scanf("%d",&T);
        while(T--){
            scanf("%d%d%d%d%d%d",&n,&m,&wx,&wy,&bx,&by);
            
            flag1=flag2=flag3=flag4=false;
            step1();
            if(flag1){
                printf("-1
    ");    continue;
            }
            step2();
            step3();
            
        }
    
        return 0;
    
    }
    View Code

    小结:

      简洁分类,转化简并。

     

  • 相关阅读:
    centos 安装 py 3.0+
    ubuntu下安装多版本Python
    DRF之注册器响应器分页器
    头部随着滚动高度的变化由透明慢慢变成不透明
    悬浮滚动
    判断某天是周几
    正则限制input只能输入大于0的数字
    原生js倒计时
    从两个时间段里分别计算出有几天工作日与周末
    sublime text3连续打出1到10的标签div
  • 原文地址:https://www.cnblogs.com/Hansue/p/11644291.html
Copyright © 2020-2023  润新知