[POJ1151]Atlantis

试题描述

There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.

输入

The input consists of several test cases. Each test case starts with a line containing a single integer n (1 <= n <= 100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area. 
The input file is terminated by a line containing a single 0. Don't process it.

输出

For each test case, your program should output one section. The first line of each section must be "Test case #k", where k is the number of the test case (starting with 1). The second one must be "Total explored area: a", where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point. 
Output a blank line after each test case.

输入示例

  1.  
  2. 25.5

输出示例

  1. Test case #
  2. Total explored area: 180.00

数据规模及约定

见“输入

题解

上一题,比上一题简单。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <cctype>
  6. #include <algorithm>
  7. using namespace std;
  8.  
  9. int read() {
  10. int x = 0, f = 1; char c = getchar();
  11. while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
  12. while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
  13. return x * f;
  14. }
  15.  
  16. #define maxn 4010
  17. int n, cnt, ca, cd;
  18. struct Rec {
  19. double x1, y1, x2, y2;
  20. Rec() {}
  21. Rec(double _1, double _2, double _3, double _4): x1(_1), y1(_2), x2(_3), y2(_4) {}
  22. } rs[maxn];
  23. struct Rec_int { int x1, y1, x2, y2; } rsi[maxn];
  24. double num[maxn<<1], A[maxn<<1], B[maxn<<1];
  25. struct Line {
  26. int l, r, x;
  27. Line() {}
  28. Line(int _1, int _2, int _3): l(_1), r(_2), x(_3) {}
  29. bool operator < (const Line& t) const { return x < t.x; }
  30. } ad[maxn], de[maxn];
  31.  
  32. double sumv[maxn<<3];
  33. int addv[maxn<<3];
  34. void build(int L, int R, int o) {
  35. if(L == R) {
  36. sumv[o] = 0.0;
  37. addv[o] = 0;
  38. return ;
  39. }
  40. int M = L + R >> 1, lc = o << 1, rc = lc | 1;
  41. build(L, M, lc); build(M+1, R, rc);
  42. sumv[o] = 0.0; addv[o] = 0;
  43. return ;
  44. }
  45. void update(int L, int R, int o, int ql, int qr, int v) {
  46. int M = L + R >> 1, lc = o << 1, rc = lc | 1;
  47. if(ql <= L && R <= qr) {
  48. addv[o] += v;
  49. if(addv[o]) sumv[o] = A[R] - A[L-1];
  50. else if(L == R) sumv[o] = 0.0;
  51. else sumv[o] = sumv[lc] + sumv[rc];
  52. return ;
  53. }
  54. if(ql <= M) update(L, M, lc, ql, qr, v);
  55. if(qr > M) update(M+1, R, rc, ql, qr, v);
  56. sumv[o] = addv[o] ? A[R] - A[L-1] : sumv[lc] + sumv[rc];
  57. return ;
  58. }
  59.  
  60. int main() {
  61. int kase = 0;
  62. while(1) {
  63. scanf("%d", &n);
  64. if(!n) break;
  65. cnt = 0;
  66. for(int i = 1; i <= n; i++) {
  67. double x1, x2, y1, y2;
  68. scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
  69. rs[i] = Rec(x1, y1, x2, y2);
  70. num[++cnt] = x1; num[++cnt] = x2;
  71. }
  72. sort(num + 1, num + cnt + 1);
  73. cnt = unique(num + 1, num + cnt + 1) - num - 1;
  74. int tcnt = cnt;
  75. for(int i = 1; i < cnt; i++) A[i] = num[i+1] - num[1];
  76. for(int i = 1; i <= n; i++) {
  77. rsi[i].x1 = lower_bound(num + 1, num + cnt + 1, rs[i].x1) - num;
  78. rsi[i].x2 = lower_bound(num + 1, num + cnt + 1, rs[i].x2) - num - 1;
  79. // printf("%d %d\n", rsi[i].x1, rsi[i].x2);
  80. }
  81. cnt = 0;
  82. for(int i = 1; i <= n; i++)
  83. num[++cnt] = rs[i].y1, num[++cnt] = rs[i].y2;
  84. sort(num + 1, num + cnt + 1);
  85. cnt = unique(num + 1, num + cnt + 1) - num - 1;
  86. for(int i = 1; i < cnt; i++) B[i] = num[i+1] - num[i];
  87. ca = cd = 0;
  88. for(int i = 1; i <= n; i++) {
  89. rsi[i].y1 = lower_bound(num + 1, num + cnt + 1, rs[i].y1) - num;
  90. rsi[i].y2 = lower_bound(num + 1, num + cnt + 1, rs[i].y2) - num;
  91. ad[++ca] = Line(rsi[i].x1, rsi[i].x2, rsi[i].y1);
  92. de[++cd] = Line(rsi[i].x1, rsi[i].x2, rsi[i].y2);
  93. }
  94.  
  95. sort(ad + 1, ad + ca + 1);
  96. // for(int i = 1; i <= ca; i++) printf("[%d %d] %d\n", ad[i].l, ad[i].r, ad[i].x);
  97. sort(de + 1, de + cd + 1);
  98. double ans = 0.0;
  99. int ka = 1, kd = 1;
  100. build(1, tcnt, 1);
  101. for(int i = 1; i <= cnt; i++) {
  102. while(ka <= ca && ad[ka].x == i) {
  103. // printf("add: [%d, %d]\n", ad[ka].l, ad[ka].r);
  104. update(1, tcnt, 1, ad[ka].l, ad[ka].r, 1), ka++;
  105. }
  106. while(kd <= cd && de[kd].x == i) {
  107. // printf("del: [%d, %d]\n", de[kd].l, de[kd].r);
  108. update(1, tcnt, 1, de[kd].l, de[kd].r, -1), kd++;
  109. }
  110. if(i < cnt) ans += sumv[1] * B[i];
  111. // printf("sumv[1]: %.2lf\n", sumv[1]);
  112. }
  113. printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++kase, ans);
  114. }
  115.  
  116. return 0;
  117. }

[POJ1151]Atlantis的更多相关文章

  1. poj1151 Atlantis && cdoj 1600艾尔大停电 矩形面积并

    题目: Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23758   Accepted: 8834 Des ...

  2. ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)

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

  3. POJ1151 Atlantis 【扫描线】

    Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16882   Accepted: 6435 Descrip ...

  4. POJ-1151 Atlantis 矩形面积并

    题目链接:http://poj.org/problem?id=1151 扫描线+离散+线段树,线段树每个节点保存的是离散后节点右边的线段. //STATUS:C++_AC_16MS_208KB #in ...

  5. poj1151 Atlantis (线段树+扫描线+离散化)

    有点难,扫描线易懂,离散化然后线段树处理有点不太好理解. 因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了. AC代码 #inc ...

  6. POJ1151 Atlantis 水题 计算几何

    http://poj.org/problem?id=1151 想学一下扫描线线段树,结果写了道水题. #include<iostream> #include<cstdio> # ...

  7. POJ1151 Atlantis 线段树扫描线

    扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...

  8. poj1151 Atlantis——扫描线+线段树

    题目:http://poj.org/problem?id=1151 经典的扫描线问题: 可以用线段树的每个点代表横向被矩形上下边分割开的每一格,这样将一个矩形的出现或消失化为线段树上的单点修改: 每个 ...

  9. POJ1151 Atlantis 扫描线算法

    题目大意 给出几个矩形对角端点坐标,求这些矩形整体覆盖的面积. 扫描线算法 整个平面被每个矩形的水平边所在直线(以后简称“水平线”)分成了几个部分,而整体覆盖面积则为每相邻的两个水平线间夹的长度(以后 ...

随机推荐

  1. 自然语言6_treebank句子解析

    #英文句子结构分析 import nltkfrom nltk.corpus import treebankt = treebank.parsed_sents('wsj_0001.mrg')[1]t.d ...

  2. smith waterman算法

    http://www.360doc.com/content/14/0106/00/14641369_342933143.shtml

  3. 在VS2013中强制IIS Express应用程序池使用经典模式

    直接在文件夹地址栏输入 %userprofile%\documents\iisexpress\config\applicationhost.config 会打开上边的配置文件 将 <siteDe ...

  4. scala入门教程:scala中的面向对象定义类,构造函数,继承

    我们知道scala中一切皆为对象,函数也是对象,数字也是对象,它是一个比java还要面向对象的语言. 定义scala的简单类 class Point (val x:Int, val y:Int) 上面 ...

  5. php对uploads文件的处理问题的解决

    解决uploads问题的要点有几点: 参考这篇文章 第一, 在php.ini文件中, 有file_uploads这一节 file_uploads = On ;是否开启文件上传功能, 该功能有很大的安全 ...

  6. linux安装软件通常会做哪些事

    一般来说,安装某个包,某个服务,某个软件时,可能会做以下事情(不一定全部) - 在安装目录: /usr/bin, /usr/lib: /usr/you_specified_bin/, /usr/you ...

  7. Memcached基础知识

    主要内容: Memcached基本的工作原理 Memcached的两阶段哈希 Memcached的数据存储方式 Memcached新建Item分配内存过程 Memcached的数据过期方式 Memca ...

  8. AngularJS API之toJson 对象转为JSON

    toJson()能把对象序列化为json 方法讲解 这个方法最多支持2个参数: angular.toJson(obj, pretty); obj 是想要转换的对象, pretty 可以调节格式化的样式 ...

  9. spring 缓存(spring自带Cache)(入门)

    spring的缓存机制,是方法纬度的缓存机制, 这就意味着我们并不用关注 底层是否使用了数据库以及通过什么方式访问的数据库: 因此,此缓存方法既适用于dao层,也适用于service层. spring ...

  10. assign与weak区别(面试)

    weak 比 assign 多了一个功能就是当属性所指向的对象消失的时候(也就是内存引用计数为0)会自动赋值为 nil ,这样再向 weak 修饰的属性发送消息就不会导致野指针操作crash. 可能不 ...