输入n个矩形,求并在一起的总面积。
线段树扫描线+离散的简单应用。
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<queue>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 2222
int cnt[maxn<<2];
double sum[maxn<<2];
double xid[maxn];
struct Seg
{
double l,r,h;
int p;
Seg(){}
Seg(double l, double r, double h, int p):l(l),r(r),h(h),p(p){}
bool operator < (const Seg& a) const
{
return h<a.h;
}
}seg[maxn];
int found(double x, int l, int r)
{
int m;
while(l<r)
{
m=(l+r)>>1;
if(xid[m]==x) return m;
if(xid[m]>x) r=m-1;
else l=m+1;
}
return l;
}
void pushup(int l, int r, int rt)
{
if(cnt[rt]) sum[rt]=xid[r+1]-xid[l];
else if(l==r) sum[rt]=0;
else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int L, int R, int p, int l, int r, int rt)
{
if(L<=l && R>=r)
{
cnt[rt]+=p;
pushup(l,r,rt);
return;
}
int m=(l+r)>>1;
if(L<=m) update(L,R,p,l,m,rt<<1);
if(R>m) update(L,R,p,m+1,r,rt<<1|1);
pushup(l,r,rt);
}
int main()
{
int i,j,k,m,n;
double a,b,c,d;
int cas=0;
while(scanf("%d",&n)==1 && n)
{
int m=0;
while(n--)
{
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
xid[++m]=a;
seg[m]=Seg(a,c,b,1);
xid[++m]=c;
seg[m]=Seg(a,c,d,-1);
}
sort(xid+1,xid+1+m);
sort(seg+1,seg+1+m);
int k= unique(xid+1,xid+1+m)-(xid+1);
memset(cnt,0,sizeof(cnt));
memset(sum,0,sizeof(sum));
double ans=0.0;
for(i=1;i<m;i++)
{
int l=found(seg[i].l,1,k);
int r=found(seg[i].r,1,k)-1;
if(l<=r) update(l,r,seg[i].p,1,k,1);
ans+=sum[1]*(seg[i+1].h-seg[i].h);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",++cas,ans);
}
}