矩形面积求并
思路:离散化之后按x轴or按y轴刷扫描线,用线段树来表示区间范围。
**被POJ的%.2f输出坑了一个多小时的我并没有心情仔细写题解,有机会再补吧
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<map>
#define lson (o<<1)
#define rson ((o<<1)|1)
using namespace std;
map<double,int> hx,hy;
map<int,int> vis;
const int maxn=105;
int T,n,p[maxn*2],val[maxn*2],tot,cnt,flag[maxn*2*4];
double x1,x2,y1,y2,ys[maxn*2],ans,st;
struct line{
int v;
double x,l,r;
};
line d[maxn*2],temp;
void build(int o,int l,int r)
{
//cout<<o<<' '<<l<<' '<<r<<endl;
flag[o]=0;
if(l==r)
{
val[l]=0;
return;
}
int mid=(l+r)/2;
build(lson,l,mid);
build(rson,mid+1,r);
}
void pushdown(int o,int l,int r)
{
if(l==r)val[l]+=flag[o];
else
{
flag[lson]+=flag[o];
flag[rson]+=flag[o];
}
flag[o]=0;
}
void addval(int o,int l,int r,int tx)
{
pushdown(o,l,r);
if(l>=hy[d[tx].r] || r<hy[d[tx].l])return;
if(l>=hy[d[tx].l] && r<hy[d[tx].r])
{
flag[o]+=d[tx].v;
pushdown(o,l,r);
return;
}
int mid=(l+r)/2;
addval(lson,l,mid,tx);
addval(rson,mid+1,r,tx);
}
double getsum(int o,int l,int r)
{
pushdown(o,l,r);
if(l==r)
return val[l]?ys[l+1]-ys[l]:0.0;
int mid=(l+r)/2;
return getsum(lson,l,mid)+getsum(rson,mid+1,r);
}
bool cmp1(int a,int b)
{
return d[a].x<d[b].x;
}
bool cmp2(double a,double b)
{
return a<b;
}
int main(void)
{
while(scanf("%d",&n))
{
if(!n)break;
build(1,1,2*maxn-1);
hx.clear();
hy.clear();
vis.clear();
for(int i=1;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
temp.l=y1;
temp.r=y2;
temp.x=x1;
temp.v=1;
d[i]=temp;
temp.x=x2;
temp.v=-1;
d[i+n]=temp;
p[i]=i;
p[i+n]=i+n;
ys[i]=y1;
ys[i+n]=y2;
}
tot=0;
sort(p+1,p+n*2+1,cmp1);
for(int i=1;i<=2*n;i++)
if(!hx[d[p[i]].x])hx[d[p[i]].x]=++tot;
cnt=0;
sort(ys+1,ys+2*n+1,cmp2);
for(int i=1;i<=2*n;i++)
if(!hy[ys[i]])hy[ys[i]]=++cnt,ys[cnt]=ys[i];
st=d[p[1]].x;ans=0;
for(int i=1;i<=2*n;i++)
{
if(!vis[p[i]])
{
vis[p[i]]=1;
ans+=(d[p[i]].x-st)*getsum(1,1,cnt-1);
//cout<<d[p[i]].x-st<<' '<<getsum(1,1,cnt-1)<<endl;
st=d[p[i]].x;
}
addval(1,1,cnt-1,p[i]);
}
printf("Test case #%d\n",++T);
printf("Total explored area: %.2f\n\n",ans);
}
}