12171 - Sculpture

来源:互联网 发布:数组方法和字符串方法 编辑:程序博客网 时间:2024/05/16 04:35

 

Imagine a box,made of copper plate. Imagine a second one, intersecting the first one, andseveral others, intersecting each other (or not). That is how the sculptor OttoBoxing constructs his sculptures. In fact he does not construct that much, heonly makes the design; the actual construction is contracted out to aconstruction company. For the calculation of the costs of construction thecompany needs to know the total area of copper plate involved. Parts of a boxthat are hidden in another box are not realized in copper, of course. (Copperis quite expensive, and prices are rising.) After construction, the totalconstruction is plunged into a bath of chemicals. To prevent this bath fromrunning over, the construction company wants to know the total volume of theconstruction. Given that a construction is a collection of boxes, you are askedto calculate the area and the volume of the construction.

Some of Otto’sdesigns are connected, others are not. Either way, we want to know the totalarea and the total volume. It might happen that the boxes completely enclosespace that is not included in any of the boxes (see the second example below).Because the liquid cannot enter that space, its volume must be added to thetotal volume. Copper plate bordering this space is superfluous, of course, soit does not add to the area.

Input

On the first lineone positive number: the number of test cases, at most 100. After that per testcase:

  • One line with an integer n (1 ≤ n ≤ 50): the number of boxes involved.
  • n lines with six positive integers x0y0z0xyz (1 ≤ x0y0z0xyz ≤ 500): the triple (x0y0z0) is the vertex of the box with the minimum values for the coordinates and the numbers xyz are the dimensions of the box (xy and z dimension, respectively). All dimensions are in centimeters. The sides of the boxes are always parallel to the coordinate axes.

Output

Per test case:

  • One line with two numbers separated by single spaces: the total amount of copper plate needed (in cm2), and the total volume (in cm3).

Sample Input

2

2

1 2 3 3 4 5

6 2 3 3 4 5

7

1 1 1 5 5 1

1 1 10 5 5 1

1 1 2 1 4 8

2 1 2 4 1 8

5 2 2 1 4 8

1 5 2 4 1 8

3 3 4 1 1 1

Sample Output

188 120

250 250

代码:

#include<cstdio>

#include<cstring>

#include<queue>

#include<algorithm>

using namespacestd;

 

const int maxn =50 + 5;

const int maxc =1000 + 1;

 

 original data

int n, x0[maxn],y0[maxn], z0[maxn], x1[maxn], y1[maxn], z1[maxn];

 

discretizationrelated

int nx, ny, nz;

int xs[maxn*2],ys[maxn*2], zs[maxn*2];

 

floodfill related

const int dx[] ={1,-1,0,0,0,0};

const int dy[] ={0,0,1,-1,0,0};

const int dz[] ={0,0,0,0,1,-1};

intcolor[maxn*2][maxn*2][maxn*2];

 

struct Cell

{

    int x, y, z;

    Cell(int x=0, int y=0, intz=0):x(x),y(y),z(z) {}

 

    bool valid() const

    {

        return x >= 0 && x < nx-1&& y >= 0 && y < ny-1 && z >= 0 && z< nz-1;

    }

 

    bool solid() const

    {

        return color[x][y][z] == 1; solid

    }

 

    bool getVis() const

    {

        return color[x][y][z] == 2; visited

    }

 

    void setVis() const

    {

        color[x][y][z] = 2;

    }

 

    Cell neighbor(int dir) const

    {

        return Cell(x+dx[dir], y+dy[dir],z+dz[dir]);

    }

 

    int volume() const

    {

        return(xs[x+1]-xs[x])*(ys[y+1]-ys[y])*(zs[z+1]-zs[z]);

    }

 

    int area(int dir) const

    {

        if(dx[dir] != 0)

        {

            return(ys[y+1]-ys[y])*(zs[z+1]-zs[z]);

        }

        else if(dy[dir] != 0)

        {

            return(xs[x+1]-xs[x])*(zs[z+1]-zs[z]);

        }

 

        return{(xs[x+1]-xs[x])*(ys[y+1]-ys[y]);}

    }

};

 

voiddiscretize(int* x, int& n)

{

    sort(x, x+n);

    n = unique(x, x+n) - x;

}

 

int ID(int* x, intn, int x0)

{

    return lower_bound(x, x + n, x0) - x;

}

 

voidfloodfill(int& v, int& s)

{

    v = 0;

    s = 0;

    Cell c;

    c.setVis();

    queue<Cell> q;

    q.push(c);

 

    while(!q.empty())

    {

        Cell c = q.front();

        q.pop();

        v += c.volume();

        for(int i = 0; i < 6; i++)

        {

            Cell c2 = c.neighbor(i);

            if(!c2.valid())

            {

                continue;

            }

 

            if(c2.solid())

            {

                s += c.area(i);

            }

            else if(!c2.getVis())

            {

                c2.setVis();

                q.push(c2);

            }

        }

    }

 

    v = maxc*maxc*maxc - v;

}

 

int main()

{

    int T;

    scanf("%d", &T);

    while(T--)

    {

        nx = ny = nz = 2;

        xs[0] = ys[0] = zs[0] = 0;

        xs[1] = ys[1] = zs[1] = maxc;

        scanf("%d", &n);

 

        for(int i = 0; i < n; i++)

        {

            scanf("%d%d%d%d%d%d",&x0[i], &y0[i], &z0[i], &x1[i], &y1[i], &z1[i]);

            x1[i] += x0[i];

           y1[i] += y0[i];

            z1[i] += z0[i];

            xs[nx++] = x0[i];

            xs[nx++] = x1[i];

            ys[ny++] = y0[i];

            ys[ny++] = y1[i];

            zs[nz++] = z0[i];

            zs[nz++] = z1[i];

        }

        discretize(xs, nx);

        discretize(ys, ny);

        discretize(zs, nz);

 

paint

        memset(color, 0, sizeof(color));

        for(int i = 0; i < n; i++)

        {

            int X1 = ID(xs, nx, x0[i]), X2 =ID(xs, nx, x1[i]);

            int Y1 = ID(ys, ny, y0[i]), Y2 =ID(ys, ny, y1[i]);

            int Z1 = ID(zs, nz, z0[i]), Z2 =ID(zs, nz, z1[i]);

            for(int X = X1; X < X2; X++)

            {

                for(int Y = Y1; Y < Y2; Y++)

                {

                    for(int Z = Z1; Z < Z2; Z++)

                    {

                        color[X][Y][Z] = 1;

                    }

                }

            }

        }

 

        int v, s;

        floodfill(v, s);

        printf("%d %d\n", s, v);

    }

 

    return 0;

}

0 0
原创粉丝点击