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 x0, y0, z0, x, y, z (1 ≤ x0, y0, z0, x, y, z ≤ 500): the triple (x0, y0, z0) is the vertex of the box with the minimum values for the coordinates and the numbers x, y, z are the dimensions of the box (x, y 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;
}