poj 3277 City Horizon (线段树 扫描线 矩形面积并)
题意: 给一些矩形,给出长和高,其中长是用区间的形式给出的,有些区间有重叠,最后求所有矩形的面积。
分析: 给的区间的范围很大,所以需要离散化,还需要把y坐标去重,不过我试了一下不去重 也不会出错,
所有的区间都能列出来,只是在查找的时候费点事。
给的矩形相当于在同一水平线上的,也就是y1坐标相当于为0,其他的就和 poj 1151 Atlantis 差不多了。
我写的思路是按照矩形面积并的思路写的:
但是还有另一种方法也是挺简单的,就是把给的矩形按照高从小到大排序,然后依次插入线段树,后面插入的
高会覆盖前面矮的,也就是覆盖了矩形的高,查找的时候按照00 11 22这种区间查找,只有找到h!=0的就是
当前的高,因为这表示这是后来插入的,也就是高的,然后乘上x的范围就是面积了。
- #include <iostream>
- #include <cstdio>
- #include <vector>
- #include <cstring>
- #include <cstdlib>
- #include <algorithm>
- #define LL __int64
- #define lson l, mid, 2*rt
- #define rson mid+1, r, 2*rt+1
- const int maxn = +;
- using namespace std;
- int n;
- double y[maxn];
- struct node
- {
- int l, r, c;
- int cnt, lf, rf;
- }tr[*maxn];
- struct Line
- {
- int x, y1, y2;
- int f;
- }line[maxn];
- bool cmp(Line a, Line b)
- {
- return a.x < b.x;
- }
- void build(int l, int r, int rt)
- {
- tr[rt].l = l; tr[rt].r = r;
- tr[rt].cnt = tr[rt].c = ;
- tr[rt].lf = y[l]; tr[rt].rf = y[r];
- if(l+==r) return;
- int mid = (l+r)/;
- build(l, mid, *rt);
- build(mid, r, *rt+);
- }
- void calen(int rt)
- {
- if(tr[rt].c>)
- {
- tr[rt].cnt = tr[rt].rf-tr[rt].lf;
- return;
- }
- if(tr[rt].l+==tr[rt].r) tr[rt].cnt = ;
- else tr[rt].cnt = tr[*rt].cnt+tr[*rt+].cnt;
- }
- void update(int rt, Line e)
- {
- if(e.y1==tr[rt].lf && e.y2==tr[rt].rf)
- {
- tr[rt].c += e.f;
- calen(rt);
- return;
- }
- if(e.y2<=tr[*rt].rf) update(*rt, e);
- else if(e.y1>=tr[*rt+].lf) update(*rt+, e);
- else
- {
- Line tmp = e;
- tmp.y2 = tr[*rt].rf;
- update(*rt, tmp);
- tmp = e;
- tmp.y1 = tr[*rt+].lf;
- update(*rt+, tmp);
- }
- calen(rt);
- }
- int main()
- {
- int i, cnt;
- LL ans;
- int a, b, h;
- while(~scanf("%d", &n))
- {
- cnt = ; ans = ;
- for(i = ; i < n; i++)
- {
- scanf("%d%d%d", &a, &b, &h);
- line[cnt].x = a; line[cnt].y1 = ;
- line[cnt].y2 = h; line[cnt].f = ;
- y[cnt++] = ;
- line[cnt].x = b; line[cnt].y1 = ;
- line[cnt].y2 = h; line[cnt].f = -;
- y[cnt++] = h;
- }
- sort(line+, line+cnt, cmp);
- sort(y+, y+cnt);
- int m = unique(y+, y+cnt)-(y+); //对y坐标去重,不去重也没错
- build(, m, );
- update(, line[]);
- for(i = ; i < cnt; i++)
- {
- ans += (LL)tr[].cnt*(line[i].x-line[i-].x);
- update(, line[i]);
- }
- printf("%I64d\n", ans);
- }
- return ;
- }
poj 3277 City Horizon (线段树 扫描线 矩形面积并)的更多相关文章
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- 离散化+线段树 POJ 3277 City Horizon
POJ 3277 City Horizon Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 18466 Accepted: 507 ...
- hdu 1828 Picture(线段树扫描线矩形周长并)
线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...
- HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)
链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...
- poj City Horizon (线段树+二分离散)
http://poj.org/problem?id=3277 City Horizon Time Limit: 2000MS Memory Limit: 65536K Total Submissi ...
- hdu1828 Picture(线段树+扫描线+矩形周长)
看这篇博客前可以看一下扫描线求面积:线段树扫描线(一.Atlantis HDU - 1542(覆盖面积) 二.覆盖的面积 HDU - 1255(重叠两次的面积)) 解法一·:两次扫描线 如图我们可以 ...
- POJ 1151 Atlantis 线段树求矩形面积并 方法详解
第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...
- hdu1542 Atlantis 线段树--扫描线求面积并
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...
- 【hdu1542】线段树求矩形面积并
分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...
随机推荐
- 大晚上装CocoaPods出现错误坑爹
大晚上装CocoaPods出现错误坑爹 [!] Pod::Executable clone 'https://github.com/CocoaPods/Specs.git' master xcrun: ...
- NSStringDrawingOptions-b
如果options参数为NSStringDrawingUsesLineFragmentOrigin,那么整个文本将以每行组成的矩形为单位计算整个文本的尺寸.(在这里有点奇怪,因为字体高度大概是13.8 ...
- 给同一个表中的两个外键写sql
一个表有两个外键都指向另一个表的主键时,如何检索他们的数据? 例如,表TableA有两个列,puserID和friendID. 表TableB有两个列,userID和userName. 我们怎样检索数 ...
- android聊天,存储聊天记录sqlite
项目中有聊天模块,需要用到打开activity的时候初始化聊天记录的情况.大致情况如下: 辅助类:ChatSQLiteHelper 在第一次时会调用oncreate方法(判断的标准是schedul ...
- mvc异步表单遇到的问题
1,mvc异步表单遇到的问题 问题:使用jqury easy ui 时提交异步数据不能请求到服务器 解决办法:经过细心调试和检测,发现jqury的加载顺序放在了easy ui之后,所以首先加 ...
- DispatcherServlet--Spring的前置控制器作用简介
参考网址:http://jinnianshilongnian.iteye.com/blog/1602617 Struts有一个ActionServlet,用来完成前置控制器(分发器)的功能.其实,所有 ...
- 编写一段程序,从标准输入读取string对象的序列直到连续出现两个相同的单词或者所有单词都读完为止。使用while循环一次读取一个单词,当一个单词连续出现两次是使用break语句终止循环。输出连续重复出现的单词,或者输出一个消息说明没有人任何单词是重复出现的。
// test14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- OI 回忆录
时间过得好快,一下子就高三了,一下子就退役了,两年的时间仿佛就在一眨眼的功夫内度过了.不过还是想回忆回忆这两年的雨雪风霜,也就当做个总结吧. 高一其实并没有什么好说的,反正就这么颓到了高二. 高二上学 ...
- EBP的妙用[无法使用ESP定律时]
1.了解EBP寄存器 在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX ...
- 【Memcache】下载和安装
下载: Win7 64bit 系统 下载过过很多版本,都无法安装,最后到这里下载,成功安装: http://blog.couchbase.com/memcached-windows-64-bit-pr ...