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;

}

  

 

你可能感兴趣的:(ZOJ)