题意

给出n个矩形的左下角和右上角的坐标,计算总的面积(相交部分只算一次)。

分析

线段树扫描线的模板题。

将每个矩形都拆成上下两条线段,然后从下网上扫,当遇到底边时就加上这个区间,遇到顶边时,就减去这个区间。这些都很好理解,但是有一个点我感觉很难受!对于普通线段树,先将区间[1,2]+1,再更新区间[2,3]+1的话,2这个点的值应该是2。但是扫描线来说,2应该是1。因为[1,3]是一条线。我们的解决办法是,在线段树[L,R]的区间内储存[L,R+1]的值

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std;
const int maxn=;
struct Node{
double l,r,h;
int state;
bool operator <(const Node & rhs)const{
return h<rhs.h;
}
Node (){}
Node (double l,double r,double h,int state):l(l),r(r),h(h),state(state){}
}node[maxn];
double v[maxn];
int n,kase;
double x1,y1,x2,y2,ans;
double sumv[*maxn];
int cover[*maxn]; void maintain(int o,int L,int R){
if(cover[o])
sumv[o]=v[R+]-v[L];
else if(L==R)
sumv[o]=;
else
sumv[o]=sumv[*o]+sumv[*o+];
}
int ql,qr,vv;
void update(int o,int L,int R){
if(ql<=L&&qr>=R){
cover[o]+=vv;
maintain(o,L,R);
return ;
}
int M=L+(R-L)/;
if(ql<=M)update(*o,L,M);
if(qr>M)update(*o+,M+,R);
maintain(o,L,R);
}
int main(){
kase=;
while(scanf("%d",&n)!=EOF&&n){
int sz=;
++kase;
for(int i=;i<=n;i++){
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
node[++sz].l=x1,node[sz].r=x2,node[sz].h=y1,node[sz].state=,v[sz]=x1;
node[++sz].l=x1,node[sz].r=x2,node[sz].h=y2,node[sz].state=-,v[sz]=x2;
}
sort(node+,node++sz);
sort(v+,v++sz);
int N=unique(v+,v++sz)-v-;
memset(sumv,,sizeof(sumv));
memset(cover,,sizeof(cover));
ans=;
for(int i=;i<sz;i++){
ql=lower_bound(v+,v++N,node[i].l)-v,qr=lower_bound(v+,v++N,node[i].r)-v-,vv=node[i].state;
update(,,N);
ans+=sumv[]*(node[i+].h-node[i].h);
}
printf("Test case #%d\n",kase);
printf("Total explored area: %.2f\n",ans);
printf("\n");
}
return ;
}

【HDU1542】Atlantis的更多相关文章

  1. 线段树+扫描线【HDU1542】Atlantis

    Description 给定一些二维空间上的矩形,求它们的面积并. 一道线段树+扫描线的板子题 然而即使我会打了,也不能灵活运用这种算法.QAQ 遇到题还是不太会. 但是这种板子题还是随随便便切的. ...

  2. 【HDU1542】Atlantis (扫描线的经典运用)

    点此看题面 大致题意: 给你\(N\)个矩形,请你求出它们覆盖的面积(重叠的面积只算一次). 扫描线 这道题是一道典型的求矩形面积并问题,是扫描线的一个经典运用.这里就不赘述了. 代码 #includ ...

  3. 【POJ1151】Atlantis(线段树,扫描线)

    [POJ1151]Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) ...

  4. 【POJ1151】Atlantis

    题目大意:给定 N 个矩形,求这些矩形的面积并. 题解:采用扫描线算法. 首先,按照矩形的横坐标排序,在纵坐标方向上维护一根扫描线被覆盖的长度,在这里采用线段树维护.统计答案时,从左到右扫描 2N 个 ...

  5. 【hdu1542】线段树求矩形面积并

    分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...

  6. 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)

    [题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...

  7. 【POJ1151】【扫描线+线段树】Atlantis

    Description There are several ancient Greek texts that contain descriptions of the fabled island Atl ...

  8. 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

  9. SCI&EI 英文PAPER投稿经验【转】

    英文投稿的一点经验[转载] From: http://chl033.woku.com/article/2893317.html 1. 首先一定要注意杂志的发表范围, 超出范围的千万别投,要不就是浪费时 ...

随机推荐

  1. functool.wraps and functools.partial

    functools.partial 通过包装手法,允许我们 "重新定义" 函数签名.  通常是将函数的部分参数给固定下来, 从而形成一个输入参数更少的新函数. functool.w ...

  2. C语言 数组排序法总结

    //快速排序法 void QuickSort(int *a, int left, int right) { int i = left; int j = right; int k = a[left]; ...

  3. idea之jrebel热部署使用教程

    JRebel是一个J2EE热部署的工具.使用它可以减少浪费8-18%的开发时间在项目的构建和部署上.虽然Java也提供了HotSpot的JVM,但是如果你修改的类中有方法名称变动的话,HotSpot就 ...

  4. javascript基础-js函数

    一.创建函数的方式 1)普通方式 function cal( num1, num2 ) { return num1+num2; } 2)使用变量初始化方式 var plus = function(nu ...

  5. jquery json string 转换 合并

    Jquery 1.9.1 var BODY = { "recipients": { "values": [] }, "subject": ' ...

  6. 谈谈GPU与FPGA的一些看法

    从几个方面来介绍一下GPU和FPGA. 从峰值性能来说,GPU(10Tflops)远远高于FPGA(<1TFlops).GPU上面成千上万个core同时跑在GHz的频率上还是非常壮观的,最新的G ...

  7. (转)Inno Setup入门(五)——添加readme文件

    本文转载自:http://blog.csdn.net/yushanddddfenghailin/article/details/17250771 这个实现起来很简单,就是在[files]段中的某个预先 ...

  8. h264 aac 封装 flv

    Part 1flvtag组成 FLV 文件结构由 FLVheader和FLVBody组成.(注意flv文件是大端格式的)FLV头组成(以c为例子,一字节对齐):FLVBody是由若干个Tag组成的:  ...

  9. java代码------计算器核心位置添加

    总结:点击等号时,什么代码 else if(str.equals("-")){ ready=true; if(c=='\0'){ num1=Double.parseDouble(j ...

  10. Java 对象的创建和使用

    1.创建对象 类名 对象名 = new 类名(): Telphone phone = new Telphone; 2.使用对象 引用对象的属性:对象名 . 属性 phone.screen = 5; / ...