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; }
相关文章推荐
- hdu 5417 RGCDQ 2015多校联合训练赛
- hdu 5316 Magician(2015多校第三场第1题)线段树单点更新+区间合并
- 实习总结
- ThinkPHP实现递归无级分类――代码少
- 基于json-lib.jar包 创建JSONArray的四个常用方法
- Android Studio 配置
- mac 下面 you have an outdated version of /usr/bin/install_name_tool installed
- Android Studio 配置
- HDU1394——线段树——Minimum Inversion Number
- Android实例-自定义程序名称、图标、全屏和可旋转方向(XE8+小米2)
- Git命令使用总结
- (七十三)Android 设置EditText光标颜色及粗细 和设定EditText的光标为显示/隐藏
- 剑指offer面试题14——调整数组顺序使奇数位于偶数前面
- uva 12325 - Zombie's Treasure Chest
- uboot 环境变量设置研究
- ViewPager左右滑动
- const 用法
- 何谓组合事务ID
- 中谷教育05 Python数据类型
- JavaScript常用事件