描述
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
Total explored area: %.2f
",iCase,res);
}
return 0;
}