zoukankan      html  css  js  c++  java
  • BZOJ3723 : PA2014Final Gra w podwajanie

    暴力搜索出所有可行的形状,可以发现本质不同的形状数只有6000个左右。

    对于每个形状,它的大小不超过$8 imes 8$,故可以按照右下角为原点重建坐标系,用一个unsigned long long来存储。

    然后对于每个中心,先进行第一步扩展,若能成功扩展,则扫描所有形状,看看是否匹配即可。

    时间复杂度$O(6000nm)$。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef unsigned long long ll;
    const int N=210,M=30000;
    int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};ll state[8][8];
    int n,m,i,j,k,ans[6]={0,1,2,4,8,16};char a[N][N],f[N][N];
    struct Shape{
    int st[N],en[N],ed,v[N][2],cnt[5][5];ll q[5][5][M];
    inline void add(int x,int y){st[++ed]=x;en[ed]=y;}
    void dfs(int x){
      if(x>ed){
        int a=0,b=0;
        for(int i=1;i<=x;i++)a=max(a,v[i][0]),b=max(b,v[i][1]);
        ll t=0;
        for(int i=1;i<=x;i++)t|=state[a-v[i][0]][b-v[i][1]];
        q[a][b][++cnt[a][b]]=t;
        return;
      }
      for(int i=0;i<4;i++){
        int X=v[st[x]][0]+dx[i],Y=v[st[x]][1]+dy[i],flag=1;
        for(int j=1;j<=x;j++)if(v[j][0]==X&&v[j][1]==Y){flag=0;break;}
        if(flag)v[en[x]][0]=X,v[en[x]][1]=Y,dfs(x+1);
      }
    }
    void init(int k){
      if(k==2){
        add(1,2);
      }
      if(k==3){
        add(1,2);
        add(1,3);
        add(2,4);
      }
      if(k==4){
        add(1,2);
        add(1,3);
        add(1,4);
        add(2,5);
        add(2,6);
        add(3,7);
        add(5,8);
      }
      if(k==5){
        add(1,2);
        add(1,3);
        add(1,4);
        add(1,5);
        add(2,6);
        add(2,7);
        add(2,8);
        add(3,9);
        add(3,10);
        add(4,11);
        add(6,12);
        add(6,13);
        add(7,14);
        add(9,15);
        add(12,16);
      }
      dfs(1);
      for(int i=0;i<5;i++)for(int j=0;j<5;j++)if(cnt[i][j]){
        sort(q[i][j]+1,q[i][j]+cnt[i][j]+1);
        int k=0;
        for(int x=1;x<=cnt[i][j];x++)if(q[i][j][x]!=q[i][j][x-1])q[i][j][++k]=q[i][j][x];
        cnt[i][j]=k;
      }
    }
    }G[6];
    inline bool check(int x,int y,int z){
      if(f[x][y]<z-1)return 0;
      if(f[x][y]>=z)return 1;
      if(z<5)return 1;
      if(check(x-1,y,1)&&check(x+1,y,2)&&check(x,y-1,3)&&check(x,y+1,4))return 1;
      if(check(x-1,y,1)&&check(x+1,y,2)&&check(x,y-1,4)&&check(x,y+1,3))return 1;
      if(check(x-1,y,1)&&check(x+1,y,3)&&check(x,y-1,2)&&check(x,y+1,4))return 1;
      if(check(x-1,y,1)&&check(x+1,y,3)&&check(x,y-1,4)&&check(x,y+1,2))return 1;
      if(check(x-1,y,1)&&check(x+1,y,4)&&check(x,y-1,2)&&check(x,y+1,3))return 1;
      if(check(x-1,y,1)&&check(x+1,y,4)&&check(x,y-1,3)&&check(x,y+1,2))return 1;
      if(check(x-1,y,2)&&check(x+1,y,1)&&check(x,y-1,3)&&check(x,y+1,4))return 1;
      if(check(x-1,y,2)&&check(x+1,y,1)&&check(x,y-1,4)&&check(x,y+1,3))return 1;
      if(check(x-1,y,2)&&check(x+1,y,3)&&check(x,y-1,1)&&check(x,y+1,4))return 1;
      if(check(x-1,y,2)&&check(x+1,y,3)&&check(x,y-1,4)&&check(x,y+1,1))return 1;
      if(check(x-1,y,2)&&check(x+1,y,4)&&check(x,y-1,1)&&check(x,y+1,3))return 1;
      if(check(x-1,y,2)&&check(x+1,y,4)&&check(x,y-1,3)&&check(x,y+1,1))return 1;
      if(check(x-1,y,3)&&check(x+1,y,1)&&check(x,y-1,2)&&check(x,y+1,4))return 1;
      if(check(x-1,y,3)&&check(x+1,y,1)&&check(x,y-1,4)&&check(x,y+1,2))return 1;
      if(check(x-1,y,3)&&check(x+1,y,2)&&check(x,y-1,1)&&check(x,y+1,4))return 1;
      if(check(x-1,y,3)&&check(x+1,y,2)&&check(x,y-1,4)&&check(x,y+1,1))return 1;
      if(check(x-1,y,3)&&check(x+1,y,4)&&check(x,y-1,1)&&check(x,y+1,2))return 1;
      if(check(x-1,y,3)&&check(x+1,y,4)&&check(x,y-1,2)&&check(x,y+1,1))return 1;
      if(check(x-1,y,4)&&check(x+1,y,1)&&check(x,y-1,2)&&check(x,y+1,3))return 1;
      if(check(x-1,y,4)&&check(x+1,y,1)&&check(x,y-1,3)&&check(x,y+1,2))return 1;
      if(check(x-1,y,4)&&check(x+1,y,2)&&check(x,y-1,1)&&check(x,y+1,3))return 1;
      if(check(x-1,y,4)&&check(x+1,y,2)&&check(x,y-1,3)&&check(x,y+1,1))return 1;
      if(check(x-1,y,4)&&check(x+1,y,3)&&check(x,y-1,1)&&check(x,y+1,2))return 1;
      if(check(x-1,y,4)&&check(x+1,y,3)&&check(x,y-1,2)&&check(x,y+1,1))return 1;
      return 0;
    }
    inline bool ok(int x,int y){
      if(x<1||x>n||y<1||y>m)return 0;
      return a[x][y];
    }
    inline bool judge(int x,int y,int z){
      int i,j,k,l;
      for(i=0;i<5;i++)for(j=0;j<5;j++){
        ll t=0;
        for(k=0;k<8;k++)for(l=0;l<8;l++)if(ok(x+i-k,y+j-l))t|=state[k][l];
        for(k=G[z].cnt[i][j];k;k--)if((G[z].q[i][j][k]&t)==G[z].q[i][j][k])return 1;
      }
      return 0;
    }
    int main(){
      for(i=0;i<8;i++)for(j=0;j<8;j++)state[i][j]=1ULL<<(i*8+j);
      for(i=2;i<=5;i++)G[i].init(i);
      scanf("%d%d",&n,&m);
      for(i=1;i<=n;i++)for(scanf("%s",a[i]+1),j=1;j<=m;j++)a[i][j]-='0';
      for(i=1;i<=n;i++)for(j=1;j<=m;j++)f[i][j]=a[i][j];
      for(k=2;k<=5;k++)for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(check(i,j,k))if(judge(i,j,k))f[i][j]++;
      for(i=1;i<=n;i++)for(j=1;j<=m;j++)printf("%d%c",ans[f[i][j]],j<m?' ':'
    ');
      return 0;
    }
    

      

  • 相关阅读:
    Spring基础系列-参数校验
    Spring基础系列-容器启动流程(1)
    Java面试系列--java基础
    RabbitMQ基础系列--客户端开发
    Spring基础系列--AOP织入逻辑跟踪
    Spring基础系列--AOP实践
    Spring基础系列-AOP源码分析
    Java设计模式之《模板模式》及使用场景
    Spring基础系列-容器启动流程(2)
    Spring基础系列-容器启动流程(1)
  • 原文地址:https://www.cnblogs.com/clrs97/p/5288942.html
Copyright © 2011-2022 走看看