Atlantis(POJ1151+线段树+扫描线)
题目链接:http://poj.org/problem?id=1151
题目:


题意:求所有矩形的面积,重合部分只算一次。
思路:扫描线入门题,推荐几篇学扫描线的博客:
1.http://www.cnblogs.com/scau20110726/archive/2013/04/12/3016765.html
2.https://blog.csdn.net/qq_38786088/article/details/78633478
3.https://blog.csdn.net/lwt36/article/details/48908031(强烈推荐!)
代码实现如下:
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; typedef long long ll;
typedef unsigned long long ull; #define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define bug printf("*********\n");
#define FIN freopen("D://code//in.txt", "r", stdin);
#define debug(x) cout<<"["<<x<<"]" <<endl;
#define IO ios::sync_with_stdio(false),cin.tie(0); const double eps = 1e-;
const int mod = ;
const int maxn = + ;
const double pi = acos(-);
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f; inline int read() {//读入挂
int ret = , c, f = ;
for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar());
if(c == '-') f = -, c = getchar();
for(; isdigit(c); c = getchar()) ret = ret * + c - '';
if(f < ) ret = -ret;
return ret;
} int n, t;
double x1, y_1, x2, y_2;
double y[]; struct Line {
double y1, y2, x;
int flag;
bool operator < (const Line& a) const {
return x < a.x;
}
}line[]; struct node {
int l, r, cover;
double lf, rf, len;
}segtree[maxn*]; void push_up(int i) {
if(segtree[i].cover > ) {
segtree[i].len = segtree[i].rf - segtree[i].lf;
} else if(segtree[i].l + == segtree[i].r) {
segtree[i].len = ;
} else {
segtree[i].len = segtree[i*].len + segtree[i*+].len;
}
} void build(int i, int l, int r) {
segtree[i].l = l, segtree[i].r = r;
segtree[i].lf = y[l], segtree[i].rf = y[r];
segtree[i].cover = segtree[i].len = ;
if(l + == r) return;
int mid = (l + r) >> ;
build(i * , l, mid);
build(i * + , mid, r);
} void update(int i, double l, double r, int flag) {
if(segtree[i].lf == l && segtree[i].rf == r) {
segtree[i].cover += flag;
push_up(i);
return;
}
if(l >= segtree[i * + ].lf) {
update(i * + , l, r, flag);
} else if(r <= segtree[i * ].rf) {
update(i * , l, r, flag);
} else {
update(i * , l, segtree[i*].rf, flag);
update(i * + , segtree[i*+].lf, r, flag);
}
push_up(i);
} int main() {
//FIN;
int icase = ;
while(~scanf("%d", &n) && n) {
t = ;
printf("Test case #%d\n", ++icase);
for(int i = ; i <= n; i++,t++) {
scanf("%lf%lf%lf%lf", &x1, &y_1, &x2, &y_2);
line[t].x = x1;
line[t].y1 = y_1;
line[t].y2 = y_2;
line[t].flag = ;
y[t] = y_1;
line[++t].x = x2;
line[t].y1 = y_1;
line[t].y2 = y_2;
line[t].flag = -;
y[t] = y_2;
}
sort(line + , line + t);
sort(y + , y + t);
build(, , t - );
double ans = ;
update(, line[].y1, line[].y2, line[].flag);
for(int i = ; i < t; i++) {
ans += segtree[].len * (line[i].x - line[i-].x);
update(, line[i].y1, line[i].y2, line[i].flag);
}
printf("Total explored area: %.2f\n\n", ans);
}
return ;
}
Atlantis(POJ1151+线段树+扫描线)的更多相关文章
- Atlantis poj1151 线段树扫描线
Atlantis poj1151 线段树扫描线 题意 题目给了n个矩形,每个矩形给了左下角和右上角的坐标,矩形可能会重叠,求的是矩形最后的面积. 题解思路 这个是我线段树扫描线的第一题,听了学长的讲解 ...
- hdu1542 Atlantis (线段树+扫描线+离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- POJ1151+线段树+扫描线
/* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...
- poj1151 Atlantis (线段树+扫描线+离散化)
有点难,扫描线易懂,离散化然后线段树处理有点不太好理解. 因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了. AC代码 #inc ...
- P - Atlantis (线段树+扫描线)
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Som ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)
传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...
- POJ 1151 Atlantis(线段树-扫描线,矩形面积并)
题目链接:http://poj.org/problem?id=1151 题目大意:坐标轴上给你n个矩形, 问这n个矩形覆盖的面积 题目思路:矩形面积并. 代码如下: #include<stdio ...
- 【POJ1151】Atlantis(线段树,扫描线)
[POJ1151]Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) ...
随机推荐
- ejabberd学习1
ejabberd是XMPP协议的一个实现,对大家的另一个意义就是,可以通过ejabberd来学习erlang. 1.从源码安装ejabberd. 可以参考ejabberd 简明配置.这个博文包括了安装 ...
- Zigbee安全基础篇Part.3
原文地址: https://www.4hou.com/wireless/14294.html 导语:在之前的文章中提供了ZigBee协议及其安全功能的简要概述.在本文中,我们将探讨可在ZigBee网络 ...
- Filezilla 绿色版 禁止升级 能用。
FileZilla还是挺好用的,但是如果钟情于 绿色版的话,肯定首选是 免安装绿色版.但是呢,能找到的所谓的免升级 绿色版,都不能用.只要是打开软件了,就会在你还没有设置更新之前,就已经升级号了.并且 ...
- QT分析之调试跟踪系统
原文地址:http://blog.163.com/net_worm/blog/static/127702419201002004518944/ 在我们前面的分析中,经常看到qWarning()和qDe ...
- java得到当前时间
SimpleDateFormat timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); java.util.Date ...
- 利用FluidMoveBehavior制作出手机通讯录平滑的效果
最近学习Blend,原来Blend制作动画等效果非常棒.下面演示一下FluidMoveBehavior应用,利用Blend中行为中的FluidMoveBehavior制作出手机通讯录平滑的效果 1.在 ...
- [COGS2652]秘术「天文密葬法」
description 题面 给个树,第\(i\)个点有两个权值\(a_i\)和\(b_i\),现在求一条长度为\(m\)的路径,使得\(\frac{\sum a_i}{\sum b_i}\)最小 d ...
- POJ1284:Primitive Roots——题解
http://poj.org/problem?id=1284 给一个奇质数p,求p的原根数量. 有一个结论:当正整数n存在原根时,其一共有phi(phi(n))个不同余的原根. 所以答案为phi(p- ...
- bzoj3524: [Poi2014]Couriers(主席树)
主席树(可持久化权值线段树)初探... 修改一个点只对树上logn个点有影响,所以新建logn个点就行了,总共新建mlogn个点. 查询一个区间[l,r],相当于将数一个一个加进树,询问第l到第r次操 ...
- 根据银行卡号码获取银行卡归属行以及logo图标
根据银行卡号码获取银行卡归属地信息接口地址,get请求 https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset= ...