Atlantis

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

Problem Description
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.
 
Input
The input file 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.

 
Output
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.

 
Sample Input
2
10 10 20 20
15 15 25 25.5
0
 
Sample Output
Test case #1
Total explored area: 180.00
 
Source
 
Recommend
linle
题目大意:求矩形并的面积.
分析:比较固定的解法:线段树+扫描线.矩形的面积公式是底乘高,每次把相同y坐标的底的长度给加起来,同时向上跳,直到遇到另外一条线位置,那么底的和*高就是扩展得到的面积,这样不断地扩展就能得到答案.具体算法可以参看:传送门
          直接套线段树会有一个问题,[x,x]在这道题中表示的是一个点,是不合法的,而线段树中确是有意义的,如果处理到[x,x+1]继续分治成[x,x],[x+1,x+1]就会出现问题,正确的做法是每次将右端点往左移一位,特判如果此时的l=r,那么就是之前的[x,x+1]这种情况,直接判掉,否则就可以像线段树那样正常地递归下去.
          这道题因为坐标比较大,需要离散化一下,因为高度是需要计算的,所以只需要离散横坐标就可以了.那么线段树记录的就是下标,每次修改一个值都必须要二分查找这个值对应的下标是哪一位.
          比较坑的一个点是数据可能会有0,我在处理的时候没考虑到这种情况,一直爆栈,主要还是离散化的部分鲁棒性不强.
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = ; struct node
{
double l, r, h;
int id;
}e[maxn]; double X[maxn], c[maxn << ], XX[maxn], ans;
int cnt, n, tot, tag[maxn << ], cas = ; bool cmp(node a, node b)
{
return a.h < b.h;
} int find(double x)
{ int l = , r = cnt, res = cnt - ;
while (l <= r)
{
int mid = (l + r) >> ;
if (X[mid] >= x)
{
res = mid;
r = mid - ;
}
else
l = mid + ;
}
return res;
} void pushup(int o, int l, int r)
{
if (tag[o])
c[o] = X[r + ] - X[l];
else
if (l == r) //没有被完全覆盖就是两个点
c[o] = ;
else
c[o] = c[o * ] + c[o * + ];
} void update(int o, int l, int r, int x, int y, int v)
{
if (x <= l && r <= y)
{
tag[o] += v;
pushup(o, l, r);
return;
}
int mid = (l + r) >> ;
if (x <= mid)
update(o * , l, mid, x, y, v);
if (y > mid)
update(o * + , mid + , r, x, y, v);
pushup(o, l, r);
} int main()
{
while (~scanf("%d", &n) , n)
{
memset(c, , sizeof(c));
memset(tag, , sizeof(tag));
ans = 0.0;
tot = cnt = ;
for (int i = ; i <= n; i++)
{
double a, b, c, d;
scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
e[++tot].l = a;
e[tot].r = c;
e[tot].h = b;
e[tot].id = ;
X[tot] = a;
e[++tot].l = a;
e[tot].r = c;
e[tot].h = d;
e[tot].id = -;
X[tot] = c;
}
sort(X + , X + tot + );
sort(e + , e + + tot, cmp);
XX[] = X[];
cnt = ;
for (int i = ; i <= tot; i++)
if (X[i] != X[i - ])
XX[++cnt] = X[i];
memcpy(X, XX, sizeof(XX));
for (int i = ; i < tot; i++)
{
int l = find(e[i].l), r = find(e[i].r) - ;
update(, , cnt, l, r, e[i].id);
ans += c[] * (e[i + ].h - e[i].h);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n", cas++, ans);
} return ;
}

Hdu1542 Atlantis的更多相关文章

  1. hdu1542 Atlantis(矩阵面积的并)

    这个题算是我的第一个扫描线的题,扫描线算是一种思想吧,用到线段树+离散化.感觉高大上. 主要参考了这位大神的博客. http://www.cnblogs.com/kuangbin/archive/20 ...

  2. HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化

    题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...

  3. hdu1542 Atlantis 线段树--扫描线求面积并

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  4. hdu1542 Atlantis (线段树+扫描线+离散化)

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

  5. hdu1542 Atlantis (线段树+矩阵面积并+离散化)

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

  6. [HDU1542]Atlantis(扫描线+线段树)

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

  7. hdu-1542 Atlantis(离散化+线段树+扫描线算法)

    题目链接: Atlantis Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/32768 K (Java/Others) ...

  8. HDU-1542 Atlantis(离散化+扫描线)

    题目大意:给n个矩形,可能重叠,求面积. 题目分析:线段树维护扫描线. 代码如下: # include<bits/stdc++.h> using namespace std; # defi ...

  9. HDU1542 Atlantis(矩形面积并)

    #pragma warning (disable:4996) #include<iostream> #include<cstring> #include<string&g ...

随机推荐

  1. fetch上传文件报错的问题(multipart: NextPart: EOF)

    技术栈 后台: gin(golang) 前端: react+antd+dva 问题 前端这边使用fetch发送http请求的时候,后端解析formData报错: multipart: NextPart ...

  2. 关于购买Redis服务器:腾讯云、阿里云还是华为云?

    个人分类: redis使用 编辑 新年伊始,很多商家都开始进行新年产品大促销,在分布是缓存Redis领域,几家大公司也是打得如火如荼,各有千秋啊. 现在市场上比较有口碑的商家有腾讯云.阿里云.华为云三 ...

  3. JDK,JRE,JVM之间的关系

    JDK包括JRE包括JVM http://java-mzd.iteye.com/blog/838514

  4. pat甲级1002

    1002. A+B for Polynomials (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue T ...

  5. 解决Ubuntu16.04 fatal error: json/json.h: No such file or directory

    参考博客 错误产生 安装json-c库之后,根据GitHub上面的readme文件链接到json-c库时出现以下错误: SDMBNJson.h:9:23: fatal error: json/json ...

  6. P4语法(3)Table,Action

    Table table是p4的匹配——动作表,定义了匹配字段(key).动作(action)和一些其他相关属性. 其处理数据包的流程: Key construction.建立其匹配字段 Key loo ...

  7. Rsyslog的三种传输协议简要介绍

    rsyslog的三种传输协议 rsyslog 可以理解为多线程增强版的syslog. rsyslog提供了三种远程传输协议,分别是: 1. UDP 传输协议 基于传统UDP协议进行远程日志传输,也是传 ...

  8. Windows Forms编程实战学习:第三章 菜单

    第三章 菜单 1,控件和容器 所有的Windows Forms控件都是从System.Windows.Forms.Control类继承的,相关类的层次结构如下图所示: MarshalByRefObje ...

  9. Servlet中常用对象及API类之间的关系

    Servlet最常用的对象: 请求对象:ServletRequest和HttpServletRequest,通过该对象获取来自客户端的请求信息 响应对象:ServletResponse和HttpSer ...

  10. rabbitmqctl 的常用命令

    # 查看服务器的状态 rabbitmqctl status   # 查看环境变量 rabbitmqctl environment   # 停止rabbitmq的应用 rabbitmqctl stop_ ...