【苏州国庆营模拟】Day2 A.divide

ε祈祈猫儿з 提交于 2019-12-01 01:28:01

题目链接

 

题意:

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

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

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

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

  $1\le T\le 10^3, \;1\le n,m\le 50, \;1\le wx,bx\le n, \; 1\le wy,by\le m ,\; (wx,wy)\neq(bx,by)$

 

分析:

  首先考虑什么时候无解。

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

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

 

  接下来分类讨论:

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

 

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

 

 

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

 

实现:

#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("\n");                }        }    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\n");    continue;          }          step2();          step3();                }        return 0;    }
View Code

 

小结:

  简洁分类,转化简并。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!