HDU1542 Atlantis(面积并)
2015-07-29 08:59
393 查看
题意:给出n个矩形的 左下角和右上角坐标,计算他们覆盖的面积。
#include <iostream> #include <stdio.h> #include <math.h> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <string> #include <string.h> #include <map> #include <set> using namespace std; #define maxn 11005 struct line { double x1,x2,y1; int c; line(){} line(double xx1,double xx2,double yy1,int cc): x1(xx1),x2(xx2),y1(yy1),c(cc){} }s[maxn];//存平行于x轴的边,同时存下一个纵坐标,用于计算竖边长度 bool clm(line x,line y) { return x.y1<y.y1; } struct node { int l,r; double len;//存某个区间覆盖的长度 int c;//c==1表示的某个线段区间完全覆盖,c==0表示不完全覆盖 }tree[maxn*4]; double x[maxn]; int n; void build(int id,int l,int r) { tree[id].l=l; tree[id].r=r; tree[id].c=0; tree[id].len=0.0; if(l!=r) { int mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); } } void pushup(int id,int l,int r) { if(tree[id].c>0)//tree[id].c>0该区间完全覆盖 tree[id].len=x[r]-x[l-1]; else if(l==r)tree[id].len=0.0;//在tree[id].c不大于0的情况下,l==r,自然覆盖为零 else//另外,在tree[id].c不大于0,就是它左右儿子的长度 tree[id].len=tree[id*2].len+tree[id*2+1].len; } void update(int id,int l,int r,int c) { if(l==tree[id].l&&tree[id].r==r)//注意这里要恰好要等于更新的区间 { tree[id].c+=c; pushup(id,tree[id].l,tree[id].r); } else { int mid=(tree[id].l+tree[id].r)/2; if(r<=mid)update(id*2,l,r,c);//如果r<=mid,说明全在左边 else if(l>mid)update(id*2+1,l,r,c);//如果l>mid,说明全在右边 else { //这种情况就是左右边都有 update(id*2,l,mid,c);//我们更新的是l~mid update(id*2+1,mid+1,r,c);//mid+1~r } pushup(id,tree[id].l,tree[id].r); } } int main() { int i,k; double x1,x2,y1,y2; int tt=1; while(cin>>n&&n) { k=0; for(i=0;i<n;i++) { cin>>x1>>y1>>x2>>y2; s[k]=line(x1,x2,y1,1); x[k]=x1; k++; s[k]=line(x1,x2,y2,-1); x[k]=x2; k++; } sort(s,s+k,clm);//x的边按照高度排序 sort(x,x+k);//x数组存的是平行于x轴每边的横坐标,用于计算横边的长度(double型) int m=1; for(i=1;i<k;i++) { if(x[i]!=x[i-1]) x[m++]=x[i]; }//取出重合的横坐标 build(1,1,m-1);//按边建树 double ans=0.0; for(i=0;i<k-1;i++) { int l=lower_bound(x,x+m-1,s[i].x1)-x;//查找s[i].x1,s[i].x2在x中的下标用于更新 int r=lower_bound(x,x+m-1,s[i].x2)-x; update(1,l+1,r,s[i].c); ans+=tree[1].len*(s[i+1].y1-s[i].y1);//每次更新后覆盖的总长度为tree[1].len //再乘以相对高度就是面积 } printf("Test case #%d\n",tt++); printf("Total explored area: %0.2f\n",ans); cout<<endl; } return 0; }
相关文章推荐
- 拾遗2015-07-28
- eclipse打断点调试进入到class文件中--解决方法
- Spring MVC详解(五) 处理器拦截器详解
- myeclipe eclipse 常遇问题:Some projects cannot be imported 、java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver、The file connot be validate
- frameset导航框架
- ios 异常捕获
- UVA 725 - Division
- webView加载html5
- mysql 警告提示Unsafe statement .The statement is unsafe because it uses a LIMIT clause
- JDK安装在配置与文档生成
- EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(六)
- 算法导论2.3-5二分查找
- CentOS 6.3下Samba服务器的安装与配置
- SIP初步
- Eclipse常见问题解决 - The method getTextContent() is undefined for the type Node.
- <c:forEach>标签的使用
- 软件工程(4-6章)
- POJ_2362_Square
- scikit-learn:3.3. Model evaluation: quantifying the quality of predictions
- Spring MVC详解(四) Controller接口控制器详解(7 )完