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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章