zoukankan      html  css  js  c++  java
  • 【实验舱国庆营模拟】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

    小结:

      简洁分类,转化简并。

     

  • 相关阅读:
    MVP模式与MVVM模式
    webpack的配置处理
    leetcode 287 Find the Duplicate Number
    leetcode 152 Maximum Product Subarray
    leetcode 76 Minimum Window Substring
    感知器算法初探
    leetcode 179 Largest Number
    leetcode 33 Search in Rotated Sorted Array
    leetcode 334 Increasing Triplet Subsequence
    朴素贝叶斯分类器初探
  • 原文地址:https://www.cnblogs.com/Hansue/p/11644291.html
Copyright © 2011-2022 走看看