//这题从十一点开始写了四十分钟 然后查错一小时+ 要吐了
这题题意是给很多矩形的左下角(x,y,z最小的那个角)和三边的长(不是x,y,z最大的那个角T-T),为组成图形的面积与表面积(包在内部的之算体积不算表面积)
解法:离散化+bfs,先把范围扩大(相当于在周围加上空气),然后bfs,遇到表面积直接加入,遇到非长方体的部分也直接加入,最后用总体积减去空气的体积,这样就可以把内部的体积计算进来而不计算其表面积。因为坐标范围比较大,要先离散化。
//其实我对这题一直耿耿于怀,当年没进省队多少与这题有关
//昨天没出题 明天周五课少 出两题
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<string> using namespace std; const int u[]={,,,,,-};
const int v[]={,-,,,,};
const int w[]={,,,-,,}; struct rec{
int x1,y1,z1,x2,y2,z2;
}; struct POINT{
int x,y,z;
}; bool vis[][][];
bool loc[][][];
int n,T,ans1,ans2;
int x[],y[],z[];
rec p[];
int numx,numy,numz; int IDX(int aim){
return lower_bound(x,x+numx,aim)-x;
} int IDY(int aim){
return lower_bound(y,y+numy,aim)-y;
} int IDZ(int aim){
return lower_bound(z,z+numz,aim)-z;
} int solve(int flag,int nowx,int nowy,int nowz){//计算表面积
if (flag==) return (x[nowx+]-x[nowx])*(z[nowz+]-z[nowz]);
if (flag==) return (x[nowx+]-x[nowx])*(z[nowz+]-z[nowz]);
if (flag==) return (x[nowx+]-x[nowx])*(y[nowy+]-y[nowy]);
if (flag==) return (x[nowx+]-x[nowx])*(y[nowy+]-y[nowy]);
if (flag==) return (z[nowz+]-z[nowz])*(y[nowy+]-y[nowy]);
if (flag==) return (z[nowz+]-z[nowz])*(y[nowy+]-y[nowy]);
return -;
} void bfs(){
queue<POINT> q;
while (!q.empty()) q.pop();
q.push((POINT){,,});
ans2=(x[]-x[])*(y[]-y[])*(z[]-z[]);
vis[][][]=;
while (!q.empty()){
POINT now=q.front();
q.pop();
for (int i=;i<;i++){
int tx=now.x+u[i];
int ty=now.y+v[i];
int tz=now.z+w[i];
if (tx< || tx>=numx- || ty< || ty>=numy- || tz< || tz>=numz- || vis[tx][ty][tz]) continue;
if (loc[tx][ty][tz]){
ans1+=solve(i,now.x,now.y,now.z);
}
else{
ans2+=(x[tx+]-x[tx])*(y[ty+]-y[ty])*(z[tz+]-z[tz]);
vis[tx][ty][tz]=;
q.push((POINT){tx,ty,tz});
}
}
}
} int main(){
scanf("%d",&T);
for (int cas=;cas<=T;cas++){
scanf("%d",&n);
for (int i=;i<n;i++){
scanf("%d%d%d%d%d%d",&p[i].x1,&p[i].y1,&p[i].z1,&p[i].x2,&p[i].y2,&p[i].z2);
p[i].x2+=p[i].x1;
p[i].y2+=p[i].y1;
p[i].z2+=p[i].z1;
x[*i+]=p[i].x1;
x[*i+]=p[i].x2;
y[*i+]=p[i].y1;
y[*i+]=p[i].y2;
z[*i+]=p[i].z1;
z[*i+]=p[i].z2;//先把坐算出来
}
x[]=;
y[]=;
z[]=;
x[*n+]=;
y[*n+]=;
z[*n+]=;//拓展范围
sort(x,x+*n+);
sort(y,y+*n+);
sort(z,z+*n+);
numx=unique(x,x+*n+)-x;
numy=unique(y,y+*n+)-y;
numz=unique(z,z+*n+)-z;//离散化
memset(loc,,sizeof(loc));
memset(vis,,sizeof(vis));
for (int now=;now<n;now++){
for (int i=IDX(p[now].x1);i<IDX(p[now].x2);i++){
for (int j=IDY(p[now].y1);j<IDY(p[now].y2);j++){
for (int k=IDZ(p[now].z1);k<IDZ(p[now].z2);k++){
loc[i][j][k]=;//记录矩形位置
}
}
}
}
ans1=;//^2
ans2=;//^3
bfs();
ans2=x[numx-]*y[numy-]*z[numz-]-ans2;//总体积减去空气体积
printf("%d %d\n",ans1,ans2);
}
return ;
}
/*
1
2
1 2 3 3 4 5
6 2 3 3 4 5 1
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 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
*/