poj1151等 矩形面积并

x,y两维,hashx并按y排序做扫描线



#include<iostream>

#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<map>
#define lson (id*2)
#define rson (id*2+1)
using namespace std;
map<double,int> hashx;
int n,Case;
double ans,x[250];
struct tree
{
int val;//每组询问仅100个点,无需lazy 
double len;
}t[1000];
struct edge
{
int l,r,v;
double y,x1,x2;
}e[250];
int cmp(edge a,edge b)
{
return a.y<b.y;
}
void pushup(int id)
{
t[id].len=t[lson].len+t[rson].len;
}
void insert(int id,int l,int r,int L,int R,int v)

{//注意lr的区间所代表的真实值,端点-1之类的要考虑好

if (r<L || R<l) return;
if (l==r)
{
t[id].val+=v;
//cout<<t[id].val<<endl;
if (t[id].val<=0)
t[id].len=0;
else
t[id].len=x[r+1]-x[l];
return;
}
int mid=(l+r)/2;
insert(lson,l,mid,L,R,v);
insert(rson,mid+1,r,L,R,v);
pushup(id);
}
int main()
{
while (cin>>n)
{
if (n==0) return 0;
//初始化
ans=0;
memset(t,0,sizeof(t));
memset(e,0,sizeof(e));
memset(x,0,sizeof(x));
hashx.clear();
//读入 
for (int i=1;i<=n;i++)
{
double x1,y1,x2,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
x[i]=e[i].x1=e[i+n].x1=x1;
x[i+n]=e[i].x2=e[i+n].x2=x2;
e[i].y=y1;
e[i+n].y=y2;
e[i].v=1;
e[i+n].v=-1;
}
//预处理&hash
sort(x+1,x+1+2*n);
sort(e+1,e+1+2*n,cmp); 
for (int i=1;i<=2*n;i++)
hashx[x[i]]=i;
for (int i=1;i<=2*n;i++)
{
e[i].l=hashx[e[i].x1];
e[i].r=hashx[e[i].x2];
}
//操作:按y扫描
for (int i=1;i<=2*n;i++)
{
double w=e[i].y-e[i-1].y;
ans+=w*t[1].len;
//cout<<t[1].len<<endl;
while(e[i].y==e[i+1].y)
{//注意同y的边要全扫完在进行下一个
insert(1,1,2*n,e[i].l,e[i].r-1,e[i].v);
i++;
}
insert(1,1,2*n,e[i].l,e[i].r-1,e[i].v);

//输出
printf("Test case #%d\nTotal explored area: %.2f\n\n",++Case,ans);
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值