[NOI97] 卫星覆盖 - 矩形切割(立方体切割)

来源:互联网 发布:mac安装office2013 编辑:程序博客网 时间:2024/05/22 10:40

题目描述

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;}

0 0