题目描述
SERCOI(Space-Earth Resource Cover-Observe lnstitute)是一个致力于利用卫星技术对空间和地球资源进行覆盖观测的组织。现在他们研制成功一种新型资源观测卫星-SERCOI-308。这种卫星可以覆盖空间直角坐标系中一定大小的立方体空间,卫星处于该立方体的中心。
其中(x,y,z)为立方体的中心点坐标,r为此中心点到立方体各个面的距离(即r为立方体高的一半).立方体的各条边均平行于相应的坐标轴。我们可以用一个四元组(x,y,z,r)描述一颗卫星的状态,它所能覆盖的空间体积V=(2r)^3=8r^3。
由于一颗卫星所能覆盖的空间体积是有限的,因此空间中可能有若干颗卫星协同工作。它们所覆盖的空间区域可能有重叠的地方,如下图所示(阴影部分表示重叠的区域)。
写一个程序,根据给定的卫星分布情况,计算它们所覆盖的总体积。
输入格式
输入文件的第一行是一个正整数N(1<=N<=10O):表示空间中的卫星总数。接下来的N行每行给出了一颗卫星的状态,用空格隔开的四个正整数x,y,z,r依次表示了该卫星所能覆盖的立方体空间的中心点坐标和半高,其中-1000<=x,y,z<=1000, 1<=r<=200。
输出格式
输出文件只有一行,包括一个正整数,表示所有这些卫星所覆盖的空间总体积。
样例数据
样例输入
3
0 0 0 3
1 –1 0 1
19 3 5 6
样例输出
1944
题目分析
好的
写三维矩形切割吧
顺便用通用切割搞搞,改个维度就可以过
源代码
通用切割
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
const int maxn=3;
struct Cube {
double left[maxn],right[maxn];
} ;
struct Universal_Cut {
Cube a[10005];
int sum;
int init() {
sum=0;
}
bool if_intersect(Cube a,Cube b) {
for(int i=0; i<maxn; i++)
if(a.left[i]>=b.right[i]||a.right[i]<=b.left[i])return false;
return true;
}
void add(double x[maxn],double y[maxn]) {
sum++;
for(int i=0; i<maxn; i++) {
a[sum].left[i]=x[i];
a[sum].right[i]=y[i];
}
}
void del(int index) {
a[index]=a[sum];
sum--;
}
void cut(Cube a,Cube b,int dimension) { //返回交集
if(dimension==maxn)return;
double k1=max(a.left[dimension],b.left[dimension]);
double k2=min(a.right[dimension],b.right[dimension]);
if(a.left[dimension]<k1) {
Cube tmp=a;
tmp.right[dimension]=k1;
add(tmp.left,tmp.right);
}
if(k2<a.right[dimension]) {
Cube tmp=a;
tmp.left[dimension]=k2;
add(tmp.left,tmp.right);
}
a.left[dimension]=k1;
a.right[dimension]=k2;
cut(a,b,dimension+1);
}
};
Universal_Cut c;
int n,ans=0;
double Bleft[maxn],Bright[maxn];
int main() {
n=Get_Int();
for(int i=1; i<=n; i++) {
int x=Get_Int(),y=Get_Int(),z=Get_Int(),h=Get_Int();
Bleft[0]=x-h,Bleft[1]=y-h,Bleft[2]=z-h,Bright[0]=x+h,Bright[1]=y+h,Bright[2]=z+h;
Cube b;
for(int i=0; i<maxn; i++) {
b.left[i]=Bleft[i];
b.right[i]=Bright[i];
}
for(int j=1; j<=c.sum; j++) {
if(!c.if_intersect(c.a[j],b))continue;
c.cut(c.a[j],b,0);
c.del(j);
j--;
}
c.add(Bleft,Bright);
}
for(int i=1; i<=c.sum; i++) {
int tmp=1;
for(int j=0; j<maxn; j++)
tmp*=c.a[i].right[j]-c.a[i].left[j];
ans+=tmp;
}
printf("%d\n",ans);
return 0;
}
三维切割
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
inline const int Get_Int() {
int num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
struct Cube {
double x1,x2,y1,y2,z1,z2;
Cube() {}
Cube(double lx,double ly,double lz,double rx,double ry,double rz):x1(lx),y1(ly),z1(lz),x2(rx),y2(ry),z2(rz) {}
} ;
struct Cut_Cube {
Cube a[10005];
int sum;
int init() {
sum=0;
}
bool if_intersect(Cube a,Cube b) {
if(a.x1>=b.x2||a.y1>=b.y2||a.z1>=b.z2||a.x2<=b.x1||a.y2<=b.y1||a.z2<=b.z1)return false;
else return true;
}
void add(double x1,double y1,double z1,double x2,double y2,double z2) {
a[++sum]=Cube(x1,y1,z1,x2,y2,z2);
}
void del(int index) {
a[index]=a[sum];
sum--;
}
double Xway_cut(int index,double x1,double y1,double z1,double x2,double y2,double z2) { //返回交集
double k1=max(x1,a[index].x1);
double k2=min(x2,a[index].x2);
if(a[index].x1<k1)add(a[index].x1,a[index].y1,a[index].z1,k1,a[index].y2,a[index].z2);
if(k2<a[index].x2)add(k2,a[index].y1,a[index].z1,a[index].x2,a[index].y2,a[index].z2);
return Yway_cut(index,k1,y1,z1,k2,y2,z2);
}
double Yway_cut(int index,double x1,double y1,double z1,double x2,double y2,double z2) {
double k1=max(y1,a[index].y1);
double k2=min(y2,a[index].y2);
if(a[index].y1<k1)add(x1,a[index].y1,a[index].z1,x2,k1,a[index].z2);
if(k2<a[index].y2)add(x1,k2,a[index].z1,x2,a[index].y2,a[index].z2);
return Zway_cut(index,x1,k1,z1,x2,k2,z2);
}
double Zway_cut(int index,double x1,double y1,double z1,double x2,double y2,double z2) {
double k1=max(z1,a[index].z1);
double k2=min(z2,a[index].z2);
if(a[index].z1<k1)add(x1,y1,a[index].z1,x2,y2,k1);
if(k2<a[index].z2)add(x1,y1,k2,x2,y2,a[index].z2);
}
};
Cut_Cube c;
int n,ans=0;
int main() {
n=Get_Int();
for(int i=1; i<=n; i++) {
int x=Get_Int(),y=Get_Int(),z=Get_Int(),h=Get_Int();
int x1=x-h,x2=x+h,y1=y-h,y2=y+h,z1=z-h,z2=z+h;
Cube b(x1,y1,z1,x2,y2,z2);
for(int j=1; j<=c.sum; j++) {
if(!c.if_intersect(c.a[j],b))continue;
c.Xway_cut(j,x1,y1,z1,x2,y2,z2);
c.del(j);
j--;
}
c.add(x1,y1,z1,x2,y2,z2);
}
for(int i=1; i<=c.sum; i++)ans+=(c.a[i].x2-c.a[i].x1)*(c.a[i].y2-c.a[i].y1)*(c.a[i].z2-c.a[i].z1);
printf("%d\n",ans);
return 0;
}