ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)
Description
Input
Output
Sample Input
2
10 10 20 20
15 15 25 25.5
0
Sample Output
Test case #1
Total explored area: 180.00
题目就是求所有矩形的并面积。
通过查阅知道了是扫描线,了解了扫描线的原理,用线段树手写了一下,结果PushUp函数写搓了。。看了AC的代码才知道了原因。
做法就是通过对纵坐标有序化,然后创建区间。
然后通过横向扫描过去,得到每段横向段的高度,乘以宽度就是面积了。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define LL long long using namespace std; //线段树
//扫描线
const int maxn = 205;
struct node
{
int lt, rt;
double height;
int num;
}tree[4*maxn]; struct Line
{
double x;
double y1, y2;
bool isLeft;
}line[maxn]; bool cmp(Line a, Line b)
{
return a.x < b.x;
} double y[maxn]; //向上更新
void PushUp(int id)
{
if(tree[id].num > 0)
{
tree[id].height = y[tree[id].rt] - y[tree[id].lt];
return;
}
if(tree[id].lt+1 == tree[id].rt)
tree[id].height = 0;
else
tree[id].height = tree[id<<1].height + tree[id<<1|1].height;
} //建立线段树
void Build(int lt, int rt, int id)
{
tree[id].lt = lt;
tree[id].rt = rt;
tree[id].height = 0;//每段的初值,根据题目要求
tree[id].num = 0;
if (lt+1 == rt)
{
//tree[id].val = 1;
return;
}
int mid = (lt + rt) >> 1;
Build(lt, mid, id<<1);
Build(mid, rt, id<<1|1);
//PushUp(id);
} //寻找符合修改的区间通过判断num进行修改
void Updata(int id,Line p)
{
if(p.y1 <= y[tree[id].lt] && p.y2 >= y[tree[id].rt])
{
if (p.isLeft > 0)
tree[id].num++;
else
tree[id].num--;
PushUp(id);
return;
}
int mid = (tree[id].lt+tree[id].rt) >> 1;
if (p.y1 < y[mid])
Updata(id<<1, p);
if (p.y2 > y[mid])
Updata(id<<1|1, p);
PushUp(id);
} int n; void Input()
{
double x1, y1, x2, y2;
int cnt = 1;
for (int i = 0; i < n; ++i)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
y[cnt] = y1;
y[cnt+1] = y2; line[cnt].x = x1;
line[cnt].y1 = y1;
line[cnt].y2 = y2;
line[cnt].isLeft = true; line[cnt+1].x = x2;
line[cnt+1].y1 = y1;
line[cnt+1].y2 = y2;
line[cnt+1].isLeft = false;
cnt += 2;
}
sort(y+1, y+1+2*n);
sort(line+1, line+1+2*n, cmp);
Build(1, 2*n, 1);
} double Work()
{
double ans = 0;
Updata(1, line[1]);
int len = 2*n;
for (int i = 2; i <= len; ++i)
{
ans += (line[i].x-line[i-1].x) * tree[1].height;
Updata(1, line[i]);
}
return ans;
} int main()
{
//freopen("test.in", "r", stdin);
int times = 1;
while (scanf("%d", &n) != EOF && n)
{
Input();
double ans = Work();
printf("Test case #%d\n", times);
printf("Total explored area: %.2lf\n\n", ans);
times++;
}
return 0;
}
ACM学习历程—POJ1151 Atlantis(扫描线 && 线段树)的更多相关文章
- poj1151 Atlantis——扫描线+线段树
题目:http://poj.org/problem?id=1151 经典的扫描线问题: 可以用线段树的每个点代表横向被矩形上下边分割开的每一格,这样将一个矩形的出现或消失化为线段树上的单点修改: 每个 ...
- ACM学习历程—HDU 5289 Assignment(线段树 || RMQ || 单调队列)
Problem Description Tom owns a company and he is the boss. There are n staffs which are numbered fro ...
- ACM学习历程—HDU 2795 Billboard(线段树)
Description At the entrance to the university, there is a huge rectangular billboard of size h*w (h ...
- poj1151 Atlantis (线段树+扫描线+离散化)
有点难,扫描线易懂,离散化然后线段树处理有点不太好理解. 因为这里是一个区间,所有在线段树中更新时,必须是一个长度大于1的区间才是有效的,比如[l,l]这是一根线段,而不是区间了. AC代码 #inc ...
- ACM学习笔记:可持久化线段树
title : 可持久化线段树 date : 2021-8-18 tags : 数据结构,ACM 可持久化线段树 可以用来解决线段树存储历史状态的问题. 我们在进行单点修改后,线段树只有logn个(一 ...
- POJ 1151 Atlantis (扫描线+线段树)
题目链接:http://poj.org/problem?id=1151 题意是平面上给你n个矩形,让你求矩形的面积并. 首先学一下什么是扫描线:http://www.cnblogs.com/scau2 ...
- [HDU1542]Atlantis(扫描线+线段树)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- 【POJ1151】Atlantis(线段树,扫描线)
[POJ1151]Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) ...
- hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积
题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> ...
随机推荐
- java 匿名类和匿名方法
package com.test; interface product{ int getPrice(); } public class News { /** * @param args */ publ ...
- 卡特兰数-Catalan数
卡特兰数的含义: 说到卡特兰数,就不得不提及卡特兰数序列.卡特兰数序列是一个整数序列.其通项公式是我们从中取出的就叫做第n个卡特兰数数,前几个卡特兰数数是:1, 1, 2, 5, 14, 42, 13 ...
- Jquery EasyUI弹出窗体
$("#btnCreate").click(function () { $("#modalwindow").html("<iframe widt ...
- 【WPF学习笔记】之如何设置下拉框读取SqlServer数据库的值:动画系列之(一)
先前条件:设置好数据库,需要三个文件CommandInfo.cs.DbHelperSQL.cs.myHelper.cs,需要修改命名空间,参照之前随笔http://www.cnblogs.com/Ow ...
- Mysql 索引增加与删除
[1]索引 索引,通俗理解,即目录. 之前说过,计算机是对现实世界的模拟.目录应用在数据库领域,即所谓的索引. 目录的作用显而易见,所以建立索引可以大大提高检索的速度. 但是,会降低更新表的速度,如对 ...
- C语言--循环结构
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvenVveW91MTMxNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- Python—发邮件总结
来自: http://my.oschina.net/jhao104/blog/613774 1.登录SMTP服务器 首先使用网上的方法(这里使用163邮箱,smtp.163.com是smtp服务器地址 ...
- authority分层
- Eclipse打jar包的方法
1.准备主清单文件 “MANIFEST.MF” Manifest-Version: 1.0 Class-Path: lib/commons-codec.jar lib/commons-httpclie ...
- Chrome 的滚动条修改.
该方法针对于win下Chrome任何版本(未测试基于Chrome内核的其他浏览器),Lunix就是目录换了一下 目录是:**\Google\Chrome\User Data\Profile 2\Use ...