[SDOI2008] 立方体覆盖 - 矩形切割(立方体切割)


题目描述

  A君近日为准备省队选拔,特意进行了数据结构的专项训练。训练过程中就遇到了“矩形面积并”这道经典问题,即:给出N个各边与坐标轴平行(垂直)的矩形,求矩形覆盖的面积之和。A君按纵坐标建立线段树后按横坐标扫描计算,轻易AC了这道题,时间复杂度为O(NlogN)。
  为了强化训练,A君将问题推广到三维空间中,即:给出N个各棱与坐标轴平行(垂直)的立方体,求立方体覆盖的体积之和。为了简化问题,令立方体均退化为正立方体,用四元组(x, y, z, r)表示一个立方体,其中x, y, z为立方体的中心点坐标,r为中心点到立方体各个面的距离(即立方体高的一半)。
  这次可难住了A君,只好请你——未来的金牌——来帮助他了。


输入格式

第一行是一个正整数N。
以下N行每行四个整数x, y, z, r,由空格隔开。


输出格式

共一个数,即覆盖的总体积。


样例数据

样例输入

3
0 0 0 3
1 –1 0 1
19 3 5 6

样例输出

1944


数据规模和约定

对于 30% 的数据,1≤N≤5
对于 70% 的数据,1≤N≤30
对于 100% 的数据,1≤N≤100
对于 100% 的数据,-1000≤x, y, z≤1000,1≤r≤200


题目分析

和NOI97卫星覆盖一毛一样
那届的同学们的确可以去拿金牌了


源代码

#include
#include
#include
#include
#include
#include
#include
#include
#include
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; iif(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; ivoid 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]if(k21);
    }
};
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; ifor(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; jprintf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(矩形切割)