題目大意:
給你一些長方體的座標,算他們的體積(包括被圍起來的體積),面積就是外表面的面積。就想象成將這些長方體放進水裏,在水佔的體積和水接觸的表面積。
分析:
最原始的想法就是按座標bfs,可以找出體積和表面積,但這一題的數組卻開不下 500*500*500已經超過一億了,辦法就是離散化。
怎麼離散化呢?因爲只有50個長方體,所以最多有100個座標 100*100*100 100萬可以接受。那麼按照常規的思路,從座標原點開始bfs,一個方塊一個方塊的搜索,並且計算體積和麪積,離散化的時候把每個點的原座標記下來方便計算,此外在程序的書寫上推薦把函數寫成結構體的成員函數,在bfs時計算和判斷都會相對來說比較簡單。
#include<bits/stdc++.h>
using namespace std;
const int maxc=1005;
const int maxn=105;
int dx[]={-1,1,0,0,0,0};
int dy[]={0,0,-1,1,0,0};
int dz[]={0,0,0,0,-1,1};
int color[maxn][maxn][maxn];
int xs[maxn],ys[maxn],zs[maxn];
int X[maxn],Y[maxn],Z[maxn],X0[maxn],Y0[maxn],Z0[maxn];
int t,n,nx,ny,nz;
struct Cell
{
int x,y,z;
Cell(int x,int y,int z):x(x),y(y),z(z) {}
void Setvis()//外圍方塊
{
color[x][y][z]=2;
}
bool getvis()
{
return color[x][y][z]==2;
}
bool solid()//想象成固體方塊
{
return color[x][y][z]==1;
}
int volume()//離散化後每個單位長方體的體積
{
return (xs[x+1]-xs[x])*(ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
}
int area(int i)//根據移動的方向計算面積
{
if(dx[i]!=0) return (ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
if(dy[i]!=0) return (xs[x+1]-xs[x])*(zs[z+1]-zs[z]);
if(dz[i]!=0) return (xs[x+1]-xs[x])*(ys[y+1]-ys[y]);
}
bool valid()//不越界
{
return x>=0&&x<nx-1&&y>=0&&y<ny-1&&z>=0&&z<nz-1;
}
Cell neighbour(int i)//行走函數
{
return Cell(x+dx[i],y+dy[i],z+dz[i]);
}
};
int ID(int *x,int n,int k)//離散化後點的編號
{
return lower_bound(x,x+n,k)-x;
}
void floodfill(int &s,int &v)//bfs
{
Cell c(0,0,0);
queue<Cell> Q;
Q.push(c);
c.Setvis();
while(!Q.empty())
{
c=Q.front();
Q.pop();
v+=c.volume();
//cout<<v<<endl;
//cout<<c.x<<" "<<c.y<<" "<<c.z<<endl;
for(int i=0;i<6;i++)
{
Cell c2=c.neighbour(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;//v計算的是外圍水的體積
}
void discretization(int *x,int &n)//計算離散化後點的個數
{
sort(x,x+n);
n=unique(x,x+n)-x;
}
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%d",&t);
nx=ny=nz=2;
xs[0]=ys[0]=zs[0]=0;
xs[1]=ys[1]=zs[1]=maxc;
for(int i=1;i<=t;i++)
{
scanf("%d%d%d%d%d%d",&X[i],&Y[i],&Z[i],&X0[i],&Y0[i],&Z0[i]);
X0[i]+=X[i];Y0[i]+=Y[i];Z0[i]+=Z[i];
xs[nx++]=X[i];xs[nx++]=X0[i];
ys[ny++]=Y[i];ys[ny++]=Y0[i];
zs[nz++]=Z[i];zs[nz++]=Z0[i];
}
discretization(xs,nx);
discretization(ys,ny);
discretization(zs,nz);
memset(color,0,sizeof(color));
for(int i=1;i<=t;i++)
{
int sx=ID(xs,nx,X[i]);int ex=ID(xs,nx,X0[i]);
int sy=ID(ys,ny,Y[i]);int ey=ID(ys,ny,Y0[i]);
int sz=ID(zs,nz,Z[i]);int ez=ID(zs,nz,Z0[i]);
for(int X=sx;X<ex;X++)
for(int Y=sy;Y<ey;Y++)
for(int Z=sz;Z<ez;Z++)
color[X][Y][Z]=1;
}
int s=0,v=0;
floodfill(s,v);
printf("%d %d\n",s,v);
}
return 0;
}