[POJ1151] Atlantis - 矩形切割


題目描述

給出n個矩形,求這些矩形面積的並。


輸入格式

輸入包含多組測試數據;
每組數據的第一行包含一個整數n(1<=n<=1000),表示矩形的個數。
接下來n行,每行四個數(不一定是整數)x1,y1,x2,y2 (0<=x1最後一行以0作爲文件的結束。


輸出格式

對於每組測試數據,輸出兩行;
第一行是“Test case #k”,k是組數 (開始爲1);
第二行爲“Total explored area: a”,a是所有矩形面積並,保留到小數點後兩位。
最後每組數據結束後輸出一空行。


樣例數據

樣例輸入

2
10 10 20 20
15 15 25 25.5
0

樣例輸出

Test case #1
Total explored area: 180.00


題目分析

矩形切割模板題
寫了一個二維的矩形切割
又用通用維度矩形切割做了一遍,看看就行了


源代碼

二維

#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 n=0,bj=1;
    char x=getchar();
    while(x<'0'||x>'9') {
        if(x=='-')bj=-1;
        x=getchar();
    }
    while(x>='0'&&x<='9') {
        n=n*10+x-'0';
        x=getchar();
    }
    return n*bj;
}
struct Square {
    double x1,x2,y1,y2;
    Square() {}
    Square(double lx,double ly,double rx,double ry):x1(lx),y1(ly),x2(rx),y2(ry) {}
} ;
struct Cut_Square {
    Square a[100005];
    int sum;
    int init() {
        sum=0;
    }
    bool if_intersect(Square a,Square b) {
        if(a.x1>=b.x2||a.y1>=b.y2||a.x2<=b.x1||a.y2<=b.y1)return false;
        else return true;
    }
    void add(double x1,double y1,double x2,double y2) {
        a[++sum]=Square(x1,y1,x2,y2);
    }
    void del(int index) {
        a[index]=a[sum];
        sum--;
    }
    void Xway_cut(int index,double x1,double y1,double x2,double y2) {
        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,k1,a[index].y2);
        if(k2<a[index].x2)add(k2,a[index].y1,a[index].x2,a[index].y2);
        Yway_cut(index,k1,y1,k2,y2);
    }
    void Yway_cut(int index,double x1,double y1,double x2,double y2) {
        double k1=max(y1,a[index].y1);
        double k2=min(y2,a[index].y2);
        if(a[index].y1<k1)add(x1,a[index].y1,x2,k1);
        if(k2<a[index].y2)add(x1,k2,x2,a[index].y2);
    }
};
Cut_Square s;
int n,cnt=0;
double ans;
int main() {
    ios::sync_with_stdio(false);
    while(true) {
        cin>>n;
        if(n==0)break;
        s.init();
        cnt++;
        ans=0;
        for(int i=1; i<=n; i++) {
            double x1,y1,x2,y2;
            cin>>x1>>y1>>x2>>y2;
            Square b(x1,y1,x2,y2);
            for(int j=1; j<=s.sum; j++) {
                if(!s.if_intersect(s.a[j],b))continue; //不相交
                s.Xway_cut(j,x1,y1,x2,y2);
                s.del(j);
                j--; //刪除完矩形移動了最後一個矩形,若j不-1可能導致原矩形未切割
            }
            s.add(x1,y1,x2,y2);
        }
        for(int i=1; i<=s.sum; i++)ans+=(s.a[i].x2-s.a[i].x1)*(s.a[i].y2-s.a[i].y1);
        printf("Test case #%d\nTotal explored area: %0.2lf\n\n",cnt,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;
}
const int maxn=2;
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,cnt=0;
double Bleft[maxn],Bright[maxn],ans=0;
int main() {
    ios::sync_with_stdio(false);
    while(true) {
        cin>>n;
        if(n==0)break;
        ans=0;
        c.init(); 
        for(int i=1; i<=n; i++) {
            cin>>Bleft[0]>>Bleft[1]>>Bright[0]>>Bright[1];
            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("Test case #%d\nTotal explored area: %0.2lf\n\n",++cnt,ans);
    }
    return 0;
}

發佈了169 篇原創文章 · 獲贊 31 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章