Description
Input
The input file is terminated by a line containing a single 0. Don't process it.
Output
Output a blank line after each test case.
借这题学会了扫描线的思想,这题题意是求矩形面积的并,对横轴建树,注意浮点数离散化,由于要用到离散前的坐标,可以用map来保存,而且map自带对key值排序功能,实现起来很方便。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iostream>
using namespace std;
const int maxn=210;//离散完了后内存消耗小了很多
struct node
{
int l,r,add;
double len;
}tree[maxn<<2];
struct L
{
int flag;
double l,r,h;
}line[maxn<<1];
double pos[maxn<<1];
int cmp(L a,L b)
{
return a.h < b.h;
}
void build(int p,int l,int r)
{
tree[p].l=l;
tree[p].r=r;
tree[p].add=0;
tree[p].len=0.0;
if(l==r)
return ;
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
}
void pushup(int p)
{
if(tree[p].add)
tree[p].len=(pos[tree[p].r+1]-pos[tree[p].l]);
else if(tree[p].l == tree[p].r)
tree[p].len=0;
else
tree[p].len=(tree[p<<1].len + tree[p<<1|1].len);
}
void update(int p,int l,int r,int val)
{
if(l<=tree[p].l && r>=tree[p].r)
{
tree[p].add+=val;
pushup(p);
return ;
}
int mid=(tree[p].l + tree[p].r)>>1;
if(r<=mid)
update(p<<1,l,r,val);
else if(l>mid)
update(p<<1|1,l,r,val);
else
{
update(p<<1,l,mid,val);
update(p<<1|1,mid+1,r,val);
}
pushup(p);
}
int main()
{
int n,p=1;
while(~scanf("%d",&n) && n)
{
int i,j;
int k=0,flag=0,cnt=0;
double ans=0;
double x1,y1,x2,y2;
map<double,int>point;
map<double,int>::iterator it;
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[cnt].l=x1;
line[cnt].r=x2;
line[cnt].h=y1;
line[cnt++].flag=1;//下边
line[cnt].l=x1;
line[cnt].r=x2;
line[cnt].h=y2;
line[cnt++].flag=-1;//上边
if(point[x1]==0)
point[x1]=++flag;
if(point[x2]==0)
point[x2]==++flag;//注意,这里的flag不是离散化后的对应坐标
}
build(1,1,flag);
for(it=point.begin();it!=point.end();it++)
{
pos[++k]=it->first;//pos数组保存离散前的坐标
it->second=k;//k才是离散前的坐标所对应的离散坐标
}
sort(line,line+cnt,cmp);
for(i=0;i<cnt-1;i++)
{
int l=point[line[i].l];
int r=point[line[i].r]-1;
update(1,l,r,line[i].flag);
ans+=(line[i+1].h-line[i].h)*tree[1].len;
}
printf("Test case #%d\n",p++);
printf("Total explored area: %.2f \n\n",ans);
}
return 0;
}