题意:给出矩形两对角点坐标,求矩形面积并。

解法:线段树+离散化。

每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线段树维护两个值:cover和len,cover表示该线段区间目前被覆盖的线段数目,len表示当前已覆盖的线段长度(化为离散前的真值),每次加入一条线段,将其y_low,y_high之间的区间染上line[i].cover,再以tree[1].len乘以接下来的线段的x坐标减去当前x坐标,即计算了一部分面积。

如图情况,将会计算三次面积:

代码:

  1. #include <iostream>
  2. #include <cmath>
  3. #include <iostream>
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <cstdlib>
  7. #include <cmath>
  8. #include <algorithm>
  9. #define eps 1e-8
  10. using namespace std;
  11. #define N 307
  12.  
  13. struct node
  14. {
  15. int cov;
  16. double len;
  17. }tree[*N];
  18.  
  19. struct Line
  20. {
  21. double y1,y2,x;
  22. int cov;
  23. }line[*N];
  24. double yy[*N];
  25.  
  26. int cmp(Line ka,Line kb)
  27. {
  28. return ka.x < kb.x;
  29. }
  30.  
  31. int bsearch(int l,int r,double x)
  32. {
  33. while(l <= r)
  34. {
  35. int mid = (l+r)/;
  36. if(fabs(yy[mid]-x) < eps)
  37. return mid;
  38. if(x > yy[mid])
  39. l = mid+;
  40. else
  41. r = mid-;
  42. }
  43. return l;
  44. }
  45.  
  46. void build(int l,int r,int rt)
  47. {
  48. tree[rt].cov = ;
  49. tree[rt].len = ;
  50. if(l == r-) return;
  51. int mid = (l+r)/;
  52. build(l,mid,*rt);
  53. build(mid,r,*rt+);
  54. }
  55.  
  56. void pushup(int l,int r,int rt)
  57. {
  58. if(tree[rt].cov)
  59. tree[rt].len = yy[r]-yy[l];
  60. else if(l+ == r)
  61. tree[rt].len = ;
  62. else
  63. tree[rt].len = tree[*rt].len + tree[*rt+].len;
  64. }
  65.  
  66. void update(int l,int r,int aa,int bb,int cover,int rt)
  67. {
  68. if(aa <= l && bb >= r)
  69. {
  70. tree[rt].cov += cover;
  71. pushup(l,r,rt);
  72. return;
  73. }
  74. if(l+ == r) return;
  75. int mid = (l+r)/;
  76. if(aa <= mid)
  77. update(l,mid,aa,bb,cover,*rt);
  78. if(bb > mid)
  79. update(mid,r,aa,bb,cover,*rt+);
  80. pushup(l,r,rt);
  81. }
  82.  
  83. int main()
  84. {
  85. int n,m,cs = ,i,j;
  86. double x1,y1,x2,y2;
  87. while(scanf("%d",&n)!=EOF && n)
  88. {
  89. m = ;
  90. for(i=;i<n;i++)
  91. {
  92. scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
  93. line[m].x = x1,line[m].y1 = y1,line[m].y2 = y2,line[m].cov = ,yy[m++] = y1;
  94. line[m].x = x2,line[m].y1 = y1,line[m].y2 = y2,line[m].cov = -,yy[m++] = y2;
  95. }
  96. m--;
  97. sort(yy+,yy+m+);
  98. int cnt = ;
  99. for(i=;i<=m;i++)
  100. {
  101. if(yy[i] != yy[i-])
  102. yy[cnt++] = yy[i];
  103. }
  104. cnt--;
  105. build(,cnt,);
  106. sort(line+,line+m+,cmp);
  107. double ans = 0.0;
  108. printf("Test case #%d\n",cs++);
  109. for(i=;i<m;i++)
  110. {
  111. int L = bsearch(,cnt,line[i].y1);
  112. int R = bsearch(,cnt,line[i].y2);
  113. update(,cnt,L,R,line[i].cov,);
  114. ans += tree[].len*(line[i+].x-line[i].x);
  115. }
  116. printf("Total explored area: %0.2lf\n\n",ans);
  117. }
  118. return ;
  119. }

POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并的更多相关文章

  1. POJ 1151 Atlantis 线段树求矩形面积并 方法详解

    第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...

  2. HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板

    好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...

  3. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

  4. hdu 1542 Atlantis (线段树扫描线)

    大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...

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

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

  6. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  7. HDU 1542 Atlantis(线段树面积并)

     描述 There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. S ...

  8. POJ 1151 HDU 1542 Atlantis(扫描线)

    题目大意就是:去一个地方探险,然后给你一些地图描写叙述这个地方,每一个描写叙述是一个矩形的右下角和左上角.地图有些地方是重叠的.所以让你求出被描写叙述的地方的总面积. 扫描线的第一道题,想了又想,啸爷 ...

  9. hdu 1542 Atlantis(线段树,扫描线)

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

随机推荐

  1. Linux Shell系列教程之(十六) Shell输入输出重定向

    本文是Linux Shell系列教程的第(十六)篇,更多Linux Shell教程请看:Linux Shell系列教程 Shell中的输出和输入的重定向是在使用中经常用到的一个功能,非常实用,今天就为 ...

  2. 说反话(c++实现)

    描述:给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出. 输入:测试输入包含一个测试用例,在一行内给出总长度不超过80的字符串.字符串由若干单词和若干空格组成,其中单词是由英文字母(大小写有 ...

  3. 被混淆的C#类库的反编译

    今天看公司以前的代码,用的是.NRT Reactor v4.4.7.5进行的混淆,直接使用.NET Reflector v8.5.0.179 是无法查看的,提示:Invalid number of d ...

  4. ASP.NET获取请求的url信息汇总

    ASP.NET获取请求的url信息汇总 最近做项目需要处理一个用代码获取当前网站的域名或ip信息的问题,于是尝试了ASP.NET中各种获取url信息的方法,在此总结一下: 在Global.asax文件 ...

  5. 一些arcgis符号库干货

    分享一些arcgis符号库干货,自己也可以参考网上的教程自己做,但尽量要符合标准规范. 下面是一些符号示例(并不一定是官方标准的): 土地利用总体规划图 水土保持图 1:5万土地利用现状 1:1万地形 ...

  6. iOS 模仿微信的照片选择器

    功能和微信的基本一致. 这个选择器使用了循环方式,保证在浏览图片时内存中只加载最多3张图片.稳定的内存大小,可定义图片尺寸.详细说明在github. 下载地址: https://github.com/ ...

  7. mac os x使用Git简易入门教程

    具体如下: 1, 首先要了解什么是Git. 简而言之,Git是一个分布式的代码版本管理工具.类似的常用工具还有SVN,CVS. 概念了解参见:http://baike.baidu.com/subvie ...

  8. C语言-05-内存分析

    一.进制 1> 内存细节 根据数据类型分配相应大小的内存空间 内存空间由高地址向低地址分配 数据一般按照从高位到低位存储 2> 常用的进制格式 十进制 ① 由0~9十个数字组成 ② 逢10 ...

  9. 小波说雨燕 第三季 构建 swift UI 之 UI组件集-视图集(二)ActionSheet视图 学习笔记

    action动作 sheet表 其实就是一种菜单 参数:1代理:谁去代理它2取消按钮标题3这个按钮标题会自动变成红色4添加设置其他按钮(不想加,设置为nil)   然后我们为这些按钮添加点击事件:   ...

  10. Android分辨率适配心得

    关于Android分辨率适配,这个是Android开发很头疼的一个问题,也需要花费相当一部分开发时间处理的一个问题,往往一个界面怎么适配就得想半天,特别是新手,也经常有人问我是怎么适配分辨率的,我也不 ...