codves 3044 矩形面积求并
题目等级 : 钻石 Diamond
题目描述 Description
输入n个矩形,求他们总共占地面积(也就是求一下面积的并)
输入描述 Input Description
可能有多组数据,读到n=0为止(不超过15组)
每组数据第一行一个数n,表示矩形个数(n<=100)
接下来n行每行4个实数x1,y1,x2,y1(0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000),表示矩形的左下角坐标和右上角坐标
输出描述 Output Description
每组数据输出一行表示答案
样例输入 Sample Input
2
10 10 20 20
15 15 25 25.5
0
样例输出 Sample Output
180.00
线段树+扫描线
本题解析参照黄学长博客http://www.hzwer.com/879.html
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,opl,opr,flag;
int col[];
double hash[],sum[],ans;
struct node
{
double x1,x2,h;
int f;
}e[];
bool cmp(node a,node b) {return a.h<b.h;}
inline void up(int k,int l,int r)
{
if(col[k]) sum[k]=hash[r+]-hash[l];
else sum[k]=sum[k<<]+sum[(k<<)+];
}
inline void change(int k,int l,int r)
{
if(l>=opl&&r<=opr)
{
col[k]+=flag;
up(k,l,r);
return;
}
int m=l+r>>;
if(opl<=m) change(k<<,l,m);
if(opr>m) change((k<<)+,m+,r);
up(k,l,r);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(!n) return ;
double x1,y1,x2,y2;
for(int i=;i<=n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
e[i*-].x1=e[i*].x1=x1;
e[i*-].x2=e[i*].x2=x2;
e[i*-].h=y1;e[i*].h=y2;
hash[i*-]=x1;hash[i*]=x2;
e[i*-].f=;e[i*].f=-;
}
sort(hash+,hash+*n+);
sort(e+,e+*n+,cmp);
ans=;
for(int i=;i<=*n;i++)
{
opl=lower_bound(hash+,hash+*n+,e[i].x1)-hash;
opr=lower_bound(hash+,hash+*n+,e[i].x2)-hash-;
flag=e[i].f;
change(,,*n);
ans+=sum[]*(e[i+].h-e[i].h);
}
printf("%.2lf\n",ans);
}
}