zoukankan      html  css  js  c++  java
  • BZOJ3619 : [Zjoi2014]璀灿光华

    终于把省选时的遗憾补上了…

    对于构造立方体:

    首先BFS构出底层,然后再逐层构造立方体

    对于计算:

    $O(n^6)$爆搜即可。

    #include<cstdio>
    #include<cstring>
    const int N=75,M=343010;
    char ch[N];
    int n,m,i,j,k,tmp,q[M],t,l,r;
    int cnt[M],side[M][6],g[M],loc[M][3],a[N][N][N],ap[N][N][N],ansl=~0U>>1,ansr,sum;
    int dx[6]={1,-1,0,0,0,0},dy[6]={0,0,1,-1,0,0},dz[6]={0,0,0,0,1,-1};
    bool vis[M];
    inline void add(int x,int y,int z,int id){vis[q[++t]=a[x][y][z]=id]=1;loc[t][0]=x,loc[t][1]=y,loc[t][2]=z;}
    inline int getup(int x){for(int i=0;i<cnt[x];i++)if(!vis[side[x][i]])return side[x][i];}
    inline int getside(int x){for(int i=0;i<cnt[x];i++)if(!vis[side[x][i]]&&cnt[side[x][i]]<5)return side[x][i];}
    inline int getcommon(int x,int y){for(int i=0;i<cnt[x];i++)if(!vis[side[x][i]])for(int j=0;j<cnt[y];j++)if(side[x][i]==side[y][j])return side[x][i];}
    void dfs(int u,int d){
      int x,y,z,i;
      for(x=loc[u][0],y=loc[u][1],z=loc[u][2];x&&y&&z&&x<=n&&y<=n&&z<=n;x+=dx[d],y+=dy[d],z+=dz[d])if(!(ap[x][y][z]++))sum+=a[x][y][z];
      if(u==t){if(ansl>sum)ansl=sum;if(ansr<sum)ansr=sum;}else for(i=0;i<6;i++)dfs(u+1,i);
      for(x=loc[u][0],y=loc[u][1],z=loc[u][2];x&&y&&z&&x<=n&&y<=n&&z<=n;x+=dx[d],y+=dy[d],z+=dz[d])if(!(--ap[x][y][z]))sum-=a[x][y][z];
    }
    int main(){
      scanf("%d",&n);m=n*n*n;
      for(i=1;i<=m;i++){
        scanf("%d",&g[i]),gets(ch+1),l=1,r=std::strlen(ch+1);
        while(ch[l]==' ')l++;
        while(ch[r]==' ')r--;ch[++r]=' ';
        for(j=l;j<=r;j++)if(ch[j]>='0'&&ch[j]<='9')(side[i][cnt[i]]*=10)+=ch[j]-'0';else cnt[i]++;
        if(cnt[i]==3)tmp=i;
      }
      add(1,1,1,tmp),add(2,1,1,side[tmp][0]),add(1,2,1,side[tmp][1]);
      for(l=2,r=3;l<r;l=r+1,r=t){
        if(loc[l][0]<n)add(loc[l][0]+1,1,1,getside(q[l]));
        for(i=l;i<r;i++)add(loc[i][0],loc[i][1]+1,1,getcommon(q[i],q[i+1]));
        if(loc[r][1]<n)add(1,loc[r][1]+1,1,getside(q[r]));
      }
      for(k=1;k<n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++)add(i,j,k+1,getup(a[i][j][k]));
      for(t=0,k=1;k<=n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++){
        a[i][j][k]=g[a[i][j][k]];
        if(!a[i][j][k])loc[++t][0]=i,loc[t][1]=j,loc[t][2]=k;
      }
      for(i=0;i<6;i++)dfs(1,i);
      return printf("%d %d",ansl,ansr),0;
    }
    

      

  • 相关阅读:
    菱形继承问题
    类的组合
    类的派生
    EasyUI的columns中列标题居中
    C#的一般处理程序中Cookie的写入、读取、清除
    JS中设置input的type="radio"默认选中
    SQL Server 分页语句查询
    CSS中设置字体样式
    C#清空StringBuilder的三种方法
    EasyUI在子tab基础上再打开新的tab标签页
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403216.html
Copyright © 2011-2022 走看看