zoukankan      html  css  js  c++  java
  • 暑假集训中期测试 Problem D: 装箱问题2 (并查集)

    Description

    有很多个棱长为1的正方体货物整齐地堆在一堆。不过有一些是悬空的, 大概是粘上去的吧。。。

    给出这些货物的相邻关系,求最小的长方体(或正方体)能装下这些货物的集装箱的体积,(集装箱棱长方向与这些正方体三个棱方向平行)。

    Input

    每组数据第一行一个n,表示有n个货物。1 <= n <= 1000

    接下来n行每行6个数,第i行表示以棱方向为轴的x轴正负、y轴正负、z轴正负方向与第i个货物相邻的货物编号(i为1~n),0表示无该位置信息。

    Output

    如果描述出现矛盾或者无法确定货物是堆在一起的,输出"What?",否则输出集装箱体积。

    Sample Input

    3
    0 0 0 0 3 2
    0 0 0 0 1 0
    0 0 0 0 0 1

    Sample Output

    3
     
    View Code
    #include <stdio.h>
    #define N 1005
    #define MIN(a,b) ((a)<(b)?(a):(b))
    #define MAX(a,b) ((a)>(b)?(a):(b))
    #define INF 0x3fffffff
    int x[N],y[N],z[N];
    int p[N];
    int n;
    void make_set()
    {
        for(int i=1;i<=n;i++)   p[i]=i,x[i]=y[i]=z[i]=0;
    }
    int find_set(int i)
    {
        int pi=p[i];
        if(i^p[i])  p[i]=find_set(p[i]);
        if(pi^p[i])
        {
            x[i]+=x[pi];
            y[i]+=y[pi];
            z[i]+=z[pi];
        }
        return p[i];
    }
    void union_set(int i,int j,int dir,int d)
    {
        int pi,pj;
        pi=find_set(i);
        pj=find_set(j);
        p[pj]=pi;
        //dir为0 表示 i与j在x方向上相邻,d=1表示j在i右边
        if(dir==0)
        {
            x[pj]=x[i]-x[j]+d;
            y[pj]=y[i]-y[j];
            z[pj]=z[i]-z[j];
        }
        else if(dir==1)
        {
            x[pj]=x[i]-x[j];
            y[pj]=y[i]-y[j]+d;
            z[pj]=z[i]-z[j];
        }
        else
        {
            x[pj]=x[i]-x[j];
            y[pj]=y[i]-y[j];
            z[pj]=z[i]-z[j]+d;
        }
    }
    int main()
    {
        int i,j;
        bool wa;
        while(~scanf("%d",&n))
        {
            make_set();
            wa=false;
            for(i=1;i<=n;i++)
            {
                for(int dir=0;dir<3;dir++)
                {
                    for(int d=1;d>=-1;d-=2)
                    {
                        scanf("%d",&j);
                        if(j==0)    continue;
                        if(find_set(i)^find_set(j)) union_set(i,j,dir,d);
                        else
                        {
                            if(dir==0 && !(y[i]==y[j]&&z[i]==z[j]&&d==x[j]-x[i]))  wa=true;
                            if(dir==1 && !(x[i]==x[j]&&z[i]==z[j]&&d==y[j]-y[i]))  wa=true;
                            if(dir==2 && !(y[i]==y[j]&&x[i]==x[j]&&d==z[j]-z[i]))  wa=true;
                        }
                    }
                }
            }
            for(i=2;!wa && i<=n;i++)   if(find_set(i)!=find_set(1))    wa=true;
            int minx=INF,maxx=-INF;
            int miny=INF,maxy=-INF;
            int minz=INF,maxz=-INF;
            if(wa)  puts("What?");
            else
            {
                for(int i=1;i<=n;i++)
                {
                    minx=MIN(minx,x[i]);    maxx=MAX(maxx,x[i]);
                    miny=MIN(miny,y[i]);    maxy=MAX(maxy,y[i]);
                    minz=MIN(minz,z[i]);    maxz=MAX(maxz,z[i]);
                }
                printf("%d\n",(maxx-minx+1)*(maxy-miny+1)*(maxz-minz+1));
            }
        }
        return 0;
    }
  • 相关阅读:
    LeetCode 3-Longest Substring Without Repeating Characters
    LeetCode 2-Add Two Numbers
    LeeCode 1-Two Sum
    Python中Lambda, filter, reduce and map 的区别
    解决Eclipse10配置Pydev不成功的问题
    Pythonxy下载链接
    546C. Soldier and Cards
    欧拉工程第58题:Spiral primes
    欧拉工程第57题:Square root convergents
    Linux编辑器vim键盘详解
  • 原文地址:https://www.cnblogs.com/algorithms/p/2615633.html
Copyright © 2011-2022 走看看