HDU 1542 Atlantis [离散化 + 扫描线 + 线段树]
来源:互联网 发布:手游模拟器mac版 编辑:程序博客网 时间:2024/05/15 06:08
http://acm.hdu.edu.cn/showproblem.php?pid=1542
给定平面上若干矩形,求出被这些矩形覆盖的区域的面积。
对所有矩形的
要高效的维护区间信息,首先想到的是线段树。然后,如果该边是“入边”,则将此边加到线段树中,否则,线段树中一定维护着这条边对应的“入边”,将它删除掉。
对于每一条“入边”,在遇到它所对应的“出边”之前,它都会影响着右边的面积,所有这些“入边”的并就是它们共同产生的影响。只要在下一条边加入之前统计出当前这部分的面积,那扫描完所有边后被这些矩形覆盖的面积就计算出来了。
还有一个问题。普通的线段树都是顶点式的,而这里要的是坐标区间式的。这有两种方法解决,一种是改变结点的闭合方式,如左闭右开,结点
#include<bits/stdc++.h>using namespace std;const double eps = 1e-9;#define rep(i,f,t) for(int i = (f),_end = (t); i <= _end; ++i)#define clr(c,x) memset(c,x,sizeof(c));#define MID int mid = (L+R)>>1;#define CHD int lc = node<<1,rc = node<<1|1;struct Node{ double x,y1,y2; int from,to; bool flag; Node(double xx,double yy1,double yy2,bool f) :x(xx),y1(yy1),y2(yy2),flag(f){} bool operator< (const Node &n2) const{ return x < n2.x; }};vector<double> vs;vector<Node> line;const int maxn = 202<<2;struct sgt{ int cov[maxn]; double len[maxn]; void init(){ clr(cov,0); clr(len,0); } void maintain(int node,int L,int R){ if(cov[node]){ len[node] = vs[R]-vs[L-1]; }else if(L != R){ CHD; len[node] = len[lc]+len[rc]; }else{ len[node] = 0; } } double query(){ return len[1]; } void update(int from,int to,int val,int node,int L,int R){ if(from <= L && R <= to){ cov[node] += val; }else{ MID;CHD; if(from <= mid)update(from,to,val,lc,L,mid); if(to > mid) update(from,to,val,rc,mid+1,R); } maintain(node,L,R); }}tree;bool equ(double x,double y){ return fabs(x-y)<eps;}bool cmp(double x,double y){ if(equ(x,y))return false; return x < y;}void pre(){ sort(vs.begin(),vs.end()); vs.erase(unique(vs.begin(),vs.end(),equ),vs.end()); rep(i,0,line.size()-1){ line[i].from = lower_bound(vs.begin(),vs.end(),line[i].y1,cmp) - vs.begin(); line[i].to = lower_bound(vs.begin(),vs.end(),line[i].y2,cmp) - vs.begin(); } sort(line.begin(),line.end());}int main(){ int n; int cas = 0; while(scanf("%d",&n), n){ tree.init(); line.clear(); vs.clear(); rep(i,1,n){ double x1,y1,x2,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); vs.push_back(y1); vs.push_back(y2); line.push_back(Node(x1,y1,y2,true)); line.push_back(Node(x2,y1,y2,false)); } pre(); double x = 0; double ans = 0; rep(i,0,line.size()-1){ double len = line[i].x-x; ans += len*tree.query(); x = line[i].x; int v = (line[i].flag?1:-1); tree.update(line[i].from+1,line[i].to,v,1,1,line.size()-1); } printf("Test case #%d\n",++cas); printf("Total explored area: %.2lf\n\n",ans); } return 0;}
0 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 线段树 (扫描线 + 离散化)
- 线段树+扫描线+离散化解poj1151 hdu 1542 ( Atlantis )
- Atlantis(扫描线+线段树+离散化)
- POJ 1542 Atlantis (线段树+扫描线+离散化)
- HDU 1542——Atlantis(线段树+面积并+离散化+扫描线)
- POJ 1151 & HDU 1542 Atlantis(扫描线模板 线段树 离散化)
- POJ1151 (HDU 1542) Atlantis【矩形面积并,线段树+离散化+扫描线模板】
- HDU 1542 Atlantis(离散化+扫描线(求并面积)+线段树)
- HDU 1542 Atlantis(矩形面积并,线段树+离散化+线扫描)
- HDU 1542 Atlantis (离散化+扫描线)
- android开发之TextView
- 记第一篇博客
- PHP实现双向链表
- Tomcat server.xml详解
- 百度地图的 LocationClient 在高德地图中要用什么来实现?
- HDU 1542 Atlantis [离散化 + 扫描线 + 线段树]
- C编译器剖析_6.3.4 汇编代码生成_为函数调用与返回产生汇编代码
- 【pintos学习笔记】(2)睡眠“忙等待”
- 二、Calendar Events 读写
- 进程间通信(二):FIFO
- 对于Thinking In Java中byte,short无符号右移的理解
- 2015年04月30日学习情况
- hdu 5210
- android 无线调试