• BZOJ3619 [Zjoi2014]璀灿光华 构造+dfs


    题意:有一个$a^3$个小正方体组成的大正方体,其中有n个正方体会向上下左右前后六个方向中的一个发出光,正方体是透光的,被照亮的正方体有个美丽值$g_{i}$,给出正方体的相邻关系,问美丽值之和的最小值和最大值。

    难点在如何建图。
    先随便找个棱角,再随便建两条棱,然后一层一层铺下去。当铺到一个新的点时,肯定已经铺好了至少一个与它相邻的点,然后再暴力算出已知与当前点相邻的点给出的每个相邻的点的出现次数,然后没被填过且出现次数最多的那个点的编号,就是当前点的编号。
    建完图跑个dfs就行了。

    #include<cstdio>
    #include<algorithm>
    #include<string>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define For(i,x,y) for (register int i=(x);i<=(y);i++)
    #define Dow(i,x,y) for (register int i=(x);i>=(y);i--)
    #define cross(i,k) for (register int i=first[k];i;i=last[i])
    char c;
    inline ll read(){
        ll x=0;int ch=getchar(),f=1;
        while (!isdigit(ch)&&(ch!='-')&&(ch!=EOF)) ch=getchar();
        if (ch=='-'){f=-1;ch=getchar();}
        while (isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        c=ch;return x*f;
    }
    const int N = 70*70*70+10;
    const int dx[6]={1,-1,0,0,0,0};
    const int dy[6]={0,0,1,-1,0,0};
    const int dz[6]={0,0,0,0,1,-1};
    struct node{
        int x,y,z;
    }l[11];
    int n,rt,tot,g[N],next[N][7],a[75][75][75],vis[N],cnt[N];
    ll Max,Min;
    inline bool check(int x,int y,int z){return x>0&&x<=n&&y>0&&y<=n&&z>0&&z<=n;}
    inline void dfs(int now,int x,int y,int z,int k){
        a[x][y][z]=now,vis[now]=1;
        if (z==n&&k==4||y==n&&k==2) return;
        if (z==n-1&&k==4||y==n-1&&k==2){
            For(i,1,next[now][0]){
                int v=next[now][i];
                if (!vis[v]&&next[v][0]==3){dfs(v,x+dx[k],y+dy[k],z+dz[k],k);break;}
            }
            return;
        }
        For(i,1,next[now][0]){
            int v=next[now][i];
            if (!vis[v]&&next[v][0]==4){dfs(v,x+dx[k],y+dy[k],z+dz[k],k);break;}
        }
    }
    int x,y,z,Vis[75][75][75];
    ll ans;
    inline ll min(ll a,ll b){return a<b?a:b;}
    inline ll max(ll a,ll b){return a>b?a:b;}
    inline void dfs(int k){
        if (k>tot){Max=max(Max,ans),Min=min(Min,ans);return;}
        For(i,0,5){
            x=l[k].x,y=l[k].y,z=l[k].z;
            while (check(x+dx[i],y+dy[i],z+dz[i])){
                x+=dx[i],y+=dy[i],z+=dz[i];
                if (!Vis[x][y][z]) ans+=1ll*g[a[x][y][z]];Vis[x][y][z]++;
            }
            dfs(k+1);
            x=l[k].x,y=l[k].y,z=l[k].z;
            while (check(x+dx[i],y+dy[i],z+dz[i])){
                x+=dx[i],y+=dy[i],z+=dz[i],Vis[x][y][z]--;
                if (!Vis[x][y][z]) ans-=1ll*g[a[x][y][z]];
            }
        }
    }
    inline void Print(){
        For(i,1,n){
            For(j,1,n){
                For(k,1,n) printf("%d ",a[i][j][k]);puts("");
            }puts("");
        }
    }
    int main(){
        //freopen("P3342.in","r",stdin);
        //freopen("P3342.out","w",stdout);
        n=read();
        For(i,1,n*n*n){
            g[i]=read();
            while (c==' ') next[i][++next[i][0]]=read();
        }
        For(i,1,n*n*n) if (next[i][0]==3){rt=i;break;}
        dfs(rt,1,1,1,4),dfs(rt,1,1,1,2);
        For(i,1,n) For(j,1,n) For(k,1,n){
            if (a[i][j][k]) continue;
            int Max=0,Max_id=0;
            for (int d=0;d<6;d+=2){
                int v=a[i-dx[d]][j-dy[d]][k-dz[d]];
                For(nxt,1,next[v][0]){
                    cnt[next[v][nxt]]++;
                    if (cnt[next[v][nxt]]>Max&&!vis[next[v][nxt]]) Max=cnt[next[v][nxt]],Max_id=next[v][nxt];
                }
            }
            a[i][j][k]=Max_id,vis[Max_id]=1;
            for (int d=0;d<6;d+=2){
                int v=a[i-dx[d]][j-dy[d]][k-dz[d]];
                For(nxt,1,next[v][0]) cnt[next[v][nxt]]--;
            }
        }
        For(i,1,n) For(j,1,n) For(k,1,n) if (!g[a[i][j][k]]) l[++tot]=(node){i,j,k};
        Max=(ll)-1e18,Min=-Max;
        dfs(1);
        printf("%lld %lld",Min,Max);
    }
    
  • 相关阅读:
    Linux账户密码安全策略设置 /etc/login.defs:
    GPS网络时间服务器安装注意事项
    ntp时间校准服务器的调试方法
    北斗网络时钟服务器的特点
    sntp时间服务器的介绍
    网络校时服务器
    综合时间码分配器介绍
    子母钟系统介绍
    智能计数器简介
    怎样选择通用计数器?
  • 原文地址:https://www.cnblogs.com/zykykyk/p/9280551.html
Copyright © 2020-2023  润新知