1036-自由堆叠的屋顶
描述
sed 同学最近突发奇想,认为伟大的建筑物的屋顶应该是“自由堆叠”出来的,他的设计方案是:将各种颜色的长方形建筑板材堆叠在一起,并保证各个板材长边、宽边均相互平行或在一条直线上,板材之间的重叠部分用连接装置固定在一起。
你的任务是计算这个“自由堆叠的屋顶”所覆盖的面积。sed 将会在屋顶平面上建立一个二维坐标系,提供给你每个长方形建筑板材左上角、右下角的坐标。为简化计算,这里忽略板材的厚度,假设它们都在同一个平面上。
输入
输入数据包含多组测试案例。
每组测试案例由N(0≤N≤100)开头,后续N行每行包含4个实数x1;y1;x2;y2 (0 <= x1 < x2 <= 100000建筑单位;0 <= y1 < y2 <= 100000建筑单位)。
(x1; y1) 、 (x2;y2)分别是长方形建筑板材左上角、右下角的坐标。
单独一个行输入0表示输入结束,无需处理。
输出
对于每个测试用例,输出以下信息: 第1行形如“Build #k”,这里k是测试用例序号(以1开始),第二行形如“Total area: a”,a是总覆盖面积,保留两位小数。
样例输入
2
10 10 20 20
15 15 25 25.5
1
10 10 20 20 0
样例输出
Build #1
Total explored area: 180.00
Build #2
Total explored area: 100.00
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; #define MAXN 201 struct Node { int l,r; int c; double lf,rf; double cnt,more; }segTree[MAXN*3]; struct Line { double x,y1,y2; int f; }line[MAXN]; bool cmp(Line a,Line b) { return a.x < b.x; } double y[MAXN]; void Build(int t,int l,int r) { segTree[t].l=l;segTree[t].r=r; segTree[t].cnt=segTree[t].c=0; segTree[t].lf=y[l]; segTree[t].rf=y[r]; if(l+1==r) return; int mid=(l+r)>>1; Build(t<<1,l,mid); Build(t<<1|1,mid,r); } void calen(int t) { if(segTree[t].c>0) { segTree[t].cnt=segTree[t].rf-segTree[t].lf; return; } if(segTree[t].l+1==segTree[t].r) segTree[t].cnt=0; else segTree[t].cnt=segTree[t<<1].cnt+segTree[t<<1|1].cnt; } void update (int t,Line e) { if(e.y1==segTree[t].lf&&e.y2==segTree[t].rf) { segTree[t].c+=e.f; calen(t); return; } if(e.y2<=segTree[t<<1].rf) update(t<<1,e); else if(e.y1>=segTree[t<<1|1].lf) update(t<<1|1,e); else { Line tmp=e; tmp.y2=segTree[t<<1].rf; update(t<<1,tmp); tmp=e; tmp.y1=segTree[t<<1|1].lf; update(t<<1|1,tmp); } calen(t); } int main() { // freopen("a.txt","r",stdin); int i,n,t,iCase=0; double x1,y1,x2,y2; while(scanf("%d",&n),n) { iCase++; t=1; for(i=1;i<=n;i++) { scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); line[t].x=x1; line[t].y1=y1; line[t].y2=y2; line[t].f=1; y[t]=y1; t++; line[t].x=x2; line[t].y1=y1; line[t].y2=y2; line[t].f=-1; y[t]=y2; t++; } sort(line+1,line+t,cmp); sort(y+1,y+t); Build(1,1,t-1); update(1,line[1]); double res=0; for(i=2;i<t;i++) { res+=segTree[1].cnt*(line[i].x-line[i-1].x); update(1,line[i]); } printf("Build #%d\nTotal explored area: %.2f\n",iCase,res); } return 0; }