求矩形的面积之和。

线段树+离散话+扫描线

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<string>
  6. #include<queue>
  7. #include<algorithm>
  8. #include<map>
  9. #include<iomanip>
  10. #define INF 99999999
  11. using namespace std;
  12.  
  13. const int MAX=+;
  14. int mark[MAX<<];//记录某个区间的下底边个数
  15. double sum[MAX<<];//记录某个区间的下底边总长度
  16. double lisan[MAX];//对x进行离散化,否则x为浮点数且很大无法进行线段树
  17.  
  18. //以横坐标作为线段(区间),对横坐标线段进行扫描
  19. //扫描的作用是每次更新下底边总长度和下底边个数,增加新面积
  20. struct seg{//线段
  21. double l,r,h;
  22. int d;
  23. seg(){}
  24. seg(double x1,double x2,double H,int c):l(x1),r(x2),h(H),d(c){}
  25. bool operator<(const seg &a)const{
  26. return h<a.h;
  27. }
  28. }s[MAX];
  29.  
  30. void Upfather(int n,int left,int right){
  31. if(mark[n])sum[n]=lisan[right+]-lisan[left];//表示该区间整个线段长度可以作为底边
  32. else if(left == right)sum[n]=;//叶子结点则底边长度为0(区间内线段长度为0)
  33. else sum[n]=sum[n<<]+sum[n<<|];
  34. }
  35.  
  36. void Update(int L,int R,int d,int n,int left,int right){
  37. if(L<=left && right<=R){//该区间是当前扫描线段的一部分,则该区间下底边总长以及上下底边个数差更新
  38. mark[n]+=d;//更新底边相差差个数
  39. Upfather(n,left,right);//更新底边长
  40. return;
  41. }
  42. int mid=left+right>>;
  43. if(L<=mid)Update(L,R,d,n<<,left,mid);
  44. if(R>mid)Update(L,R,d,n<<|,mid+,right);
  45. Upfather(n,left,right);
  46. }
  47.  
  48. int search(double key,double* x,int n){
  49. int left=,right=n-;
  50. while(left<=right){
  51. int mid=left+right>>;
  52. if(x[mid] == key)return mid;
  53. if(x[mid]>key)right=mid-;
  54. else left=mid+;
  55. }
  56. return -;
  57. }
  58.  
  59. int main(){
  60. int n,num=;
  61. double x1,x2,y1,y2;
  62. while(cin>>n,n){
  63. int k=;
  64. for(int i=;i<n;++i){
  65. cin>>x1>>y1>>x2>>y2;
  66. lisan[k]=x1;
  67. s[k++]=seg(x1,x2,y1,);
  68. lisan[k]=x2;
  69. s[k++]=seg(x1,x2,y2,-);
  70. }
  71. sort(lisan,lisan+k);
  72. sort(s,s+k);
  73. int m=;
  74. for(int i=;i<k;++i)//去重复端点
  75. if(lisan[i] != lisan[i-])lisan[m++]=lisan[i];
  76. double ans=;
  77. //memset(mark,0,sizeof mark);
  78. //memset(sum,0,sizeof sum);//如果下面是i<k-1,则要初始化,因为如果对第k-1条,线段扫描时会使得mark,sum为0才不用初始化的
  79. for(int i=;i<k;++i){//扫描线段
  80. int L=search(s[i].l,lisan,m);
  81. int R=search(s[i].r,lisan,m)-;
  82. Update(L,R,s[i].d,,,m-);//扫描线段时更新底边长度和底边相差个数
  83. ans+=sum[]*(s[i+].h-s[i].h);//新增加面积
  84. }
  85. printf("Test case #%d\nTotal explored area: %.2lf\n\n",++num,ans);
  86. }
  87. return ;
  88. }

hdu 1542 Atlantis的更多相关文章

  1. (HDU 1542) Atlantis 矩形面积并——扫描线

    n个矩形,可以重叠,求面积并. n<=100: 暴力模拟扫描线.模拟赛大水题.(n^2) 甚至网上一种“分块”:分成n^2块,每一块看是否属于一个矩形. 甚至这个题就可以这么做. n<=1 ...

  2. HDU 1542 Atlantis(矩形面积并)

    HDU 1542 Atlantis 题目链接 题意:给定一些矩形,求面积并 思路:利用扫描线,因为这题矩形个数不多,直接暴力扫就能够了.假设数据大.就要用线段树 代码: #include <cs ...

  3. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

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

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

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

  5. HDU 1542 Atlantis(扫描线算法)

    题意:给出n个矩形的左下角左边和右上角坐标,求这n个矩形的面积并 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 典型的扫描线算法的题目 什么是 ...

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

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

  7. hdu 1542 Atlantis(段树&amp;扫描线&amp;面积和)

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

  8. hdu 1542 Atlantis 段树区,并寻求,,,尼玛真坑人数据,不要打开一小阵!

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

  9. (中等) HDU 1542 Atlantis,扫描线。

    Problem Description There are several ancient Greek texts that contain descriptions of the fabled is ...

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

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

随机推荐

  1. Union all的用法实例sql

    ---Union all的用法实例sqlSELECT TOP (100) PERCENT ID, bid_user_id, UserName, amount, createtime, borrowTy ...

  2. js克隆

    一.有什么用 不破坏原对象的属性 引入一些概念~ 原始数据类型(5种):undefined.null.number.string.boolean 引用数据类型(1种,也叫复合数据类型):object ...

  3. 转: HTML的电子邮件链接标签mailto用法详解

    mailto是网页设计制作中的一个非常实用的html标签,许多拥有个人网页的朋友都喜欢在网站的醒目位置处写上自己的电子邮件地址,这样网页浏览者一旦用鼠标单击一下由mailto组成的超级连接后,就能自动 ...

  4. 二模 (11) day1

    第一题: 题目大意:用邻接矩阵给出一棵树(边权非负)上N个节点相互之间的最短路距离,求这棵树所有边权的和. 解题过程: 1.暂时还没想出来,待AC. 第二题: 题目大意:给出一些单词,然后建立Trie ...

  5. Oracle、Mysql、Sql Server语句的区别

    1.空值的处理——判断是否为空,为空时取一个值,不为空时取另一个值 1).Sql Server 中 ISNULL(check_expression,replacement_value) 解释:如果ch ...

  6. PhpStorm WebMatrix xDebug 配置开发环境

    1.首先下载WebMatrix安装程序,下载地址 http://www.microsoft.com/web/webmatrix/  安装步骤 参考:http://www.jb51.net/softjc ...

  7. struts2 类型转换

    概述 从一个 HTML 表单到一个 Action 对象, 类型转换是从字符串到非字符串. 在 struts2 中, 把请求参数映射到 action  属性的工作由 Parameters 拦截器负责, ...

  8. Python的平凡之路(1)

    2016-07-26   一.Python简介   Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.它的特点如下: 面向对象.解释语言.交互性.模块化.动态性.高级语言.可移植.可 ...

  9. T-sql语句

    在用代码编辑数据库时,首先要启动WAMPSERVER 1.创建表 create table Car ( Code varchar(50) primary key , Name varchar(50) ...

  10. JAVA调用系统命令或可执行程序--返回一个Runtime运行时对象,然后启动另外一个进程来执行命令

    通过 java.lang.Runtime 类可以方便的调用操作系统命令,或者一个可执行程序,下面的小例子我在windows和linux分别测试过,都通过.基本原理是,首先通过 Runtime.getR ...