您的位置:首页 > 其它

HDU1542 线扫描求矩形面积并

2015-07-29 16:32 316 查看
原题的链接为:http://acm.hdu.edu.cn/showproblem.php?pid=1542

这道题是最简单的先扫描的例题,适合初学线扫描的认真仔细理解的一道题。其他的线扫描的题都是在这上面的加深,比如矩形面积并,周长等,思想都是一样的,只是更新部分有的差别而已。说来也就,建树,去重,最后加一条边,计算一次矩形的面积。线扫描的题最主要的就是考虑好状态的更新。


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define nn 110

struct node
{
int l,r,v;
double len;
}tree[nn<<3];

struct seg
{
double l,r,h;
int f;//-1表示上边,1表示下边
}s[nn<<1];
double pos[nn<<1];

bool cmp(seg a,seg b)
{
return a.h<b.h;
}
int binary(double c,int low,int top)//二分查找该点的离散值
{
while(low<=top)
{
int mid=(low+top)>>1;
if(pos[mid]==c)     return mid;
else if(pos[mid]>c) top=mid;
else low=mid+1;
}
return -1;
}
void build(int ll,int rr,int rt)//建树
{
tree[rt].l=ll;  tree[rt].r=rr;  tree[rt].v=0;
if(ll==rr)  return;
int mid=(ll+rr)>>1;
build(ll,mid,rt<<1);
build(mid+1,rr,rt<<1|1);
}
void getlen(int rt)//长度更新
{
if(tree[rt].v)//该区间被覆盖
{
tree[rt].len=pos[tree[rt].r+1]-pos[tree[rt].l];
}
else if(tree[rt].l==tree[rt].r)//更新的区间为一个区间
{
tree[rt].len=0;
}
else//更新的区间不为一个点,由他的两个儿子节点来更新他的长度
{
tree[rt].len=tree[rt<<1].len+tree[rt<<1|1].len;
}
}
void updata(int ll,int rr,int c,int rt)//更新的区间查找
{
if(tree[rt].l==ll && tree[rt].r==rr)
{
tree[rt].v+=c;
getlen(rt);
return ;
}
int mid=(tree[rt].l+tree[rt].r)>>1;
if(rr<=mid)
{
updata(ll,rr,c,rt<<1);
}
else if(ll>mid)
{
updata(ll,rr,c,rt<<1|1);
}
else
{
updata(ll,mid,c,rt<<1);
updata(mid+1,rr,c,rt<<1|1);
}
getlen(rt);
}
int main()
{
int n,t=1;
while(scanf("%d",&n)&&n)
{
int num=0;
for(int i=0;i<n;i++)
{
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
s[num].l=x1;   s[num].r=x2;    s[num].h=y1;    s[num].f=1;
s[num+1].l=x1;   s[num+1].r=x2;    s[num+1].h=y2;    s[num+1].f=-1;
pos[num]=x1;   pos[num+1]=x2;
num+=2;
}
sort(pos,pos+num);//离散化
sort(s,s+num,cmp);
int m=1;
for(int i=1;i<num;i++)//去重
{
if(pos[i]!=pos[i-1])
pos[m++]=pos[i];
}
build(0,m-1,1);

double ans=0;//记录面积
for(int i=0;i<num;i++)
{

int l=binary(s[i].l,0,m-1);
int r=binary(s[i].r,0,m-1)-1;
printf("%d %d\n",l,r);
updata(l,r,s[i].f,1);
ans+=(s[i+1].h-s[i].h)*tree[1].len;

}
printf("Test case #%d\n",t++);
printf("Total explored area: %.2lf\n\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: