[POJ1151]Atlantis
[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.
输入示例
25.5
输出示例
Test case #
Total explored area: 180.00
数据规模及约定
见“输入”
题解
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 4010
int n, cnt, ca, cd;
struct Rec {
double x1, y1, x2, y2;
Rec() {}
Rec(double _1, double _2, double _3, double _4): x1(_1), y1(_2), x2(_3), y2(_4) {}
} rs[maxn];
struct Rec_int { int x1, y1, x2, y2; } rsi[maxn];
double num[maxn<<1], A[maxn<<1], B[maxn<<1];
struct Line {
int l, r, x;
Line() {}
Line(int _1, int _2, int _3): l(_1), r(_2), x(_3) {}
bool operator < (const Line& t) const { return x < t.x; }
} ad[maxn], de[maxn]; double sumv[maxn<<3];
int addv[maxn<<3];
void build(int L, int R, int o) {
if(L == R) {
sumv[o] = 0.0;
addv[o] = 0;
return ;
}
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
build(L, M, lc); build(M+1, R, rc);
sumv[o] = 0.0; addv[o] = 0;
return ;
}
void update(int L, int R, int o, int ql, int qr, int v) {
int M = L + R >> 1, lc = o << 1, rc = lc | 1;
if(ql <= L && R <= qr) {
addv[o] += v;
if(addv[o]) sumv[o] = A[R] - A[L-1];
else if(L == R) sumv[o] = 0.0;
else sumv[o] = sumv[lc] + sumv[rc];
return ;
}
if(ql <= M) update(L, M, lc, ql, qr, v);
if(qr > M) update(M+1, R, rc, ql, qr, v);
sumv[o] = addv[o] ? A[R] - A[L-1] : sumv[lc] + sumv[rc];
return ;
} int main() {
int kase = 0;
while(1) {
scanf("%d", &n);
if(!n) break;
cnt = 0;
for(int i = 1; i <= n; i++) {
double x1, x2, y1, y2;
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
rs[i] = Rec(x1, y1, x2, y2);
num[++cnt] = x1; num[++cnt] = x2;
}
sort(num + 1, num + cnt + 1);
cnt = unique(num + 1, num + cnt + 1) - num - 1;
int tcnt = cnt;
for(int i = 1; i < cnt; i++) A[i] = num[i+1] - num[1];
for(int i = 1; i <= n; i++) {
rsi[i].x1 = lower_bound(num + 1, num + cnt + 1, rs[i].x1) - num;
rsi[i].x2 = lower_bound(num + 1, num + cnt + 1, rs[i].x2) - num - 1;
// printf("%d %d\n", rsi[i].x1, rsi[i].x2);
}
cnt = 0;
for(int i = 1; i <= n; i++)
num[++cnt] = rs[i].y1, num[++cnt] = rs[i].y2;
sort(num + 1, num + cnt + 1);
cnt = unique(num + 1, num + cnt + 1) - num - 1;
for(int i = 1; i < cnt; i++) B[i] = num[i+1] - num[i];
ca = cd = 0;
for(int i = 1; i <= n; i++) {
rsi[i].y1 = lower_bound(num + 1, num + cnt + 1, rs[i].y1) - num;
rsi[i].y2 = lower_bound(num + 1, num + cnt + 1, rs[i].y2) - num;
ad[++ca] = Line(rsi[i].x1, rsi[i].x2, rsi[i].y1);
de[++cd] = Line(rsi[i].x1, rsi[i].x2, rsi[i].y2);
} sort(ad + 1, ad + ca + 1);
// for(int i = 1; i <= ca; i++) printf("[%d %d] %d\n", ad[i].l, ad[i].r, ad[i].x);
sort(de + 1, de + cd + 1);
double ans = 0.0;
int ka = 1, kd = 1;
build(1, tcnt, 1);
for(int i = 1; i <= cnt; i++) {
while(ka <= ca && ad[ka].x == i) {
// printf("add: [%d, %d]\n", ad[ka].l, ad[ka].r);
update(1, tcnt, 1, ad[ka].l, ad[ka].r, 1), ka++;
}
while(kd <= cd && de[kd].x == i) {
// printf("del: [%d, %d]\n", de[kd].l, de[kd].r);
update(1, tcnt, 1, de[kd].l, de[kd].r, -1), kd++;
}
if(i < cnt) ans += sumv[1] * B[i];
// printf("sumv[1]: %.2lf\n", sumv[1]);
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++kase, ans);
} return 0;
}
[POJ1151]Atlantis的更多相关文章
- poj1151 Atlantis && cdoj 1600艾尔大停电 矩形面积并
题目: Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 23758 Accepted: 8834 Des ...
- ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)
Description There are several ancient Greek texts that contain descriptions of the fabled island Atl ...
- POJ1151 Atlantis 【扫描线】
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16882 Accepted: 6435 Descrip ...
- POJ-1151 Atlantis 矩形面积并
题目链接:http://poj.org/problem?id=1151 扫描线+离散+线段树,线段树每个节点保存的是离散后节点右边的线段. //STATUS:C++_AC_16MS_208KB #in ...
- poj1151 Atlantis (线段树+扫描线+离散化)
有点难,扫描线易懂,离散化然后线段树处理有点不太好理解. 因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了. AC代码 #inc ...
- POJ1151 Atlantis 水题 计算几何
http://poj.org/problem?id=1151 想学一下扫描线线段树,结果写了道水题. #include<iostream> #include<cstdio> # ...
- POJ1151 Atlantis 线段树扫描线
扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...
- poj1151 Atlantis——扫描线+线段树
题目:http://poj.org/problem?id=1151 经典的扫描线问题: 可以用线段树的每个点代表横向被矩形上下边分割开的每一格,这样将一个矩形的出现或消失化为线段树上的单点修改: 每个 ...
- POJ1151 Atlantis 扫描线算法
题目大意 给出几个矩形对角端点坐标,求这些矩形整体覆盖的面积. 扫描线算法 整个平面被每个矩形的水平边所在直线(以后简称“水平线”)分成了几个部分,而整体覆盖面积则为每相邻的两个水平线间夹的长度(以后 ...
随机推荐
- xbmc的静态链接办法
XBMC是一个相当酷的音频/视频播放器,号称家庭影视中心. 我是希望静态将一些库链接进可执行程序的,这样我用的ArchLinux就不用天天在更新一些东西了 但XBMC试了很多次,编译成功后,总是在运行 ...
- Javascript权威指南——第一章Javascript概述
示例:javascript贷款计算器 相关技术: 1.如何在文档中查找元素: 2.如何通过表单input元素来获取用户的输入数据: 3.如何通过文档元素来设置HTML内容: 4.如何将数据存储在浏览器 ...
- (转)Rest介绍
参考文献:Rest简介 REST是一种组织Web服务的架构,其只在架构方面提出了一系列约束. 关于Restful的无状态 所以在stackoverflow中,我们常常会看到有人问:我现在使用了这样一种 ...
- 使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【三】——Web Api入门
系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 经过前2节的介绍,我们已经把数据访问层搭建好了,从本章开始就是Web Api部分了.在正式开 ...
- TeXmacs - 所见即所得 - 专业排版软件
所见即所得,支持中文,很好用, 容易奔溃,奔溃进入不了程序时,删除文件夹 C:\Users\Perelman\AppData\Roaming\TeXmacs
- ecshop mobile 文件介绍
mobile手机端 1.common位置:include\apps\default\common\ function.php show_message 成功跳转页面 其他页面引用 show_m ...
- Brew Command Not Found
安装了brew后,居然找不到brew命令.于是uninstall后再次install,居然还是Brew Command Not Found. 解决办法: http://stackoverflow.co ...
- 使用Topshelf 开发windows服务
在业务系统中,我们为了调度一些自动执行的任务或从队列中消费一些消息,所以基本上都会涉及到后台服务的开发.如果用windows service开发,非常不爽的一件事就是:调试相对麻烦,而且你还需要了解 ...
- centos 7.0 编译安装mysql 5.6.22 再次总结 成功编译安装~ 越来越熟练了~
查找php.ini文件所在位置 [root@localhost /]# find -name php.ini ./usr/etc/php/etc/php.ini mysql官网的安装说明http:// ...
- javascript模块简单写法
写法1: (function (wd, doc) { var mw = {}; mw.noConflict = noConflict; var _$ = wd.$; wd.$ = mw; functi ...