hdu 1542 Atlantis(线段树,扫描线)
来源:互联网 发布:环球人物和看天下知乎 编辑:程序博客网 时间:2024/05/16 15:51
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542
题意:n个矩阵,给出每个矩阵的左下和右上两个点的坐标,求出所有矩形总的覆盖面积。
扫描线问题,因为坐标是浮点型,那就必须把坐标离散化,我这直接上map了。
再来就是求这个面积的方式了:我这是向y轴映射,那么就保存每一条竖线,包扩该条竖线的x坐标,上下两个y坐标,还有用lr保存这条竖线是左边(1)那条还是右边(-1)那条,然后将所有的竖边按x从小到大排序,再一条一条地插入。看图:
先插入第一条竖边A1A2,再查询整棵数被覆盖的长度dy(即求出y坐标之差),这时候dy*(下一条边的x-插入这的条边的x)就等于第一部分的面积,以此类推。
插入A1A2可以求第一部分面积
插入B1B2可以求第二部分面积
插入C1C2可以求第三部分面积
最后一条不用插入
还有用1和-1标识左右边在这里也能看出来,当插入C1C2的时候,-1和插入A1A2时的1相抵消,表示这个区间不再覆盖,就避免了后面再计算时错误判断dy的值。
代码:
#include<cstring>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#define MAXN 1050using namespace std;struct ele{double x,yu,yd;int lr;bool operator < (ele t) const{return x<t.x;}}a[MAXN*2];struct node{int l,r;int cover;}t[MAXN*5];double yy[MAXN*2];void construct(int l,int r,int p){t[p].l=l,t[p].r=r,t[p].cover=0;if(r-l<=1) return ;int m=(l+r)>>1;construct(l,m,p*2);construct(m,r,p*2+1);}void modify(int l,int r,int val,int p){if(t[p].l==l&&t[p].r==r){t[p].cover+=val;return ;}int m=(t[p].l+t[p].r)>>1;if(r<=m)modify(l,r,val,p*2);else if(l>=m)modify(l,r,val,p*2+1);else{modify(l,m,val,p*2);modify(m,r,val,p*2+1);}}void query(double &ans,int p){if(t[p].cover){ans+=yy[t[p].r]-yy[t[p].l];return ;}else if(t[p].r-t[p].l>=1){t[p*2].cover+=t[p].cover,t[p*2+1].cover+=t[p].cover;query(ans,p*2);query(ans,p*2+1);t[p*2].cover-=t[p].cover,t[p*2+1].cover-=t[p].cover;}}int main(){int n,i,j,cas=1;double x1,x2,y1,y2;map<double,int> hash;while(scanf("%d",&n)&&n){for(i=1,j=1;i<=n;i++,j+=2){scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);a[j].x=x1,a[j].yd=y1,a[j].yu=y2;a[j].lr=1;a[j+1].x=x2,a[j+1].yd=y1,a[j+1].yu=y2;a[j+1].lr=-1;yy[j]=y1,yy[j+1]=y2;}sort(a+1,a+1+n*2);sort(yy+1,yy+1+2*n);int up=unique(yy+1,yy+1+2*n)-yy-1;for(i=1;i<=up;i++)hash[yy[i]]=i;double res=0,dy;construct(1,up,1);for(i=1;i<2*n;i++){dy=0;modify(hash[a[i].yd],hash[a[i].yu],a[i].lr,1);query(dy,1);res+=dy*(a[i+1].x-a[i].x);}printf("Test case #%d\n",cas++);printf("Total explored area: %.2lf\n\n",res);}return 0;}
- hdu 1542 Atlantis 线段树扫描线
- HDU 1542 Atlantis(线段树:扫描线)
- 【HDU】1542 Atlantis 线段树+扫描线
- HDU 1542 Atlantis(线段树扫描线)
- hdu 1542 Atlantis(线段树+扫描线)
- hdu 1542 Atlantis 线段树 + 扫描线
- HDU 1542 Atlantis 线段树+扫描线
- HDU - 1542 Atlantis(线段树 扫描线)
- HDU 1542 Atlantis 【线段树+扫描线】
- HDU 1542 Atlantis 线段树+扫描线
- HDU 1542 Atlantis(线段树+离散化+扫描线)
- hdu 1542 Atlantis(线段树,扫描线)
- hdu 1542 Atlantis (线段树+离散化+扫描线)
- HDU 1542 - Atlantis (线段树 扫描线)
- HDU 1542 && POJ 1151 Atlantis(线段树+扫描线)
- poj 1151 hdu 1542 atlantis (线段树+扫描线)
- HDU 1542 Atlantis(线段树扫描线,面积并)
- HDU 1542 Atlantis (线段树 +离散化+ 扫描线)
- <Linux+Qt>时间控制事件触发
- 杭电水题之1076
- 共享内存(System V)
- 探究一道字符串模式匹配问题
- 信号量(System V)
- hdu 1542 Atlantis(线段树,扫描线)
- hdu 4036 Rolling Hongshu
- 线程安全
- 输入法切换
- hdu 3488 Tour (最小权匹配 / 费用流)
- Android版Ibatis开源的ORM框架Aibatis介绍
- 音视频封装格式和编码格式
- 应用程序控制(自动启动、登录、退出等)
- Setup Factory 9.0 中的几个问题