题目链接:
http://poj.org/problem?id=1151
题意:
求矩形并集的面积。
思路:
想象一条竖线从最左边扫描到最右边,竖线上被矩形覆盖的地方可以确定,即可计算出被覆盖长度。
用线段树维护竖线上被覆盖的长度。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100;
struct Rec
{
double x1,y1,x2,y2;
};
struct Line
{
bool operator<(const Line &t)const{return x<t.x;}
double x;
int y1,y2,c;
};
int n,cy,cl;
double y[maxn*2];
Rec rec[maxn];
Line line[maxn*2];
int dat[maxn*2*4];
double sum[maxn*2*4];
void change(int c,int a,int b,int k,int l,int r)
{
if(a<=l&&b>=r)
{
dat[k]+=c;
if(dat[k]==0)
{
if(r-l==1)
sum[k]=0;
else sum[k]=sum[2*k+1]+sum[2*k+2];
}
else sum[k]=y[r]-y[l];
}
else
{
int m=(l+r)>>1;
if(a<m)change(c,a,b,2*k+1,l,m);
if(b>m)change(c,a,b,2*k+2,m,r);
if(dat[k]==0)
sum[k]=sum[2*k+1]+sum[2*k+2];
}
}
void discrete()//离散化
{
sort(y,y+cy);
cy=unique(y,y+cy)-y;
}
int main()
{
int k=0;
while(scanf("%d",&n)&&n)
{
cy=0;
for(int i=0;i<n;++i)
{
scanf("%lf%lf%lf%lf",&rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2);
y[cy++]=rec[i].y1;
y[cy++]=rec[i].y2;
}
discrete();
cl=0;
for(int i=0;i<n;++i)
{
line[cl].x=rec[i].x1;
line[cl].y1=lower_bound(y,y+cy,rec[i].y1)-y;
line[cl].y2=lower_bound(y,y+cy,rec[i].y2)-y;;
line[cl++].c=1;
line[cl].x=rec[i].x2;
line[cl].y1=lower_bound(y,y+cy,rec[i].y1)-y;
line[cl].y2=lower_bound(y,y+cy,rec[i].y2)-y;;
line[cl++].c=-1;
}
sort(line,line+cl);
memset(dat,0,sizeof(dat));
memset(sum,0,sizeof(sum));
double ans=0;
change(line[0].c,line[0].y1,line[0].y2,0,0,cy);
double pre=line[0].x;
for(int i=1;i<cl;++i)
{
ans+=(line[i].x-pre)*sum[0];
change(line[i].c,line[i].y1,line[i].y2,0,0,cy);
pre=line[i].x;
}
printf("Test case #%d\nTotal explored area: %.2f\n\n",++k,ans);
}
return 0;
}