POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)
题目原网址:http://poj.org/problem?id=1177
题目中文翻译:



解题思路:
总体思路:
1.沿X轴离散化建树
2.按Y值从小到大排序平行与X轴的边,然后顺序处理
如果遇到矩形下面那条边则插入到线段树中,遇到矩形上面的边则将相应的边删除掉
根据线段树当前的状态统计长度
第二点是本题的核心思想,偶再举个例:
第一次求出的部分很好理解.
第二次求出的为什么会少了中间那部分.那是因为插入的新线段覆盖了第一条,此时线段树返回的长度是新的那一条的长度,将这个值再减去上次的就少了中间那部分
第三次因为是矩形的上边,所以要删除在那条长的线段.此时的线段树返回的则是第一次的长度,将此值减去第二次返回值,再取其负值就是红色X轴那部分了
最后那条X轴的,再补上就行了.
需要注意的就是离散化以后一定要去掉重复元素,否则会出错的。
转载自:传送门
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; struct kkk {
int l,r;//线段树表示区间范围
int cnt;//有效长度
int lf,rf;//实际左右端点
int numseg;//分支数,一个分支对应两条竖线
int c;//记录覆盖情况
bool lc,rc;//左右半覆盖情况
}s[]; struct ll {
int y;
int x1,x2;
int f;//表示出入边,入边为1,出边为-1(自己想想为什么)
}l[]; int x[]; bool cmp(ll a,ll b) {
return a.y < b.y;
} void build(int i,int le,int r) {//建树
s[i].l = le;
s[i].r = r;
s[i].lf = x[le];
s[i].rf = x[r];
s[i].cnt = ;
s[i].numseg = ;
s[i].c = ;
s[i].lc = s[i].rc = false;
if(le + == r) return ;
int mid = (le + r) / ;
build(i << ,le,mid);
build((i << ) | ,mid,r);
} void calen(int i) {//计算长度
if(s[i].c > ) {
s[i].cnt = s[i].rf - s[i].lf;
s[i].numseg = ;
s[i].lc = s[i].rc = true;
return ;
}
if(s[i].l + == s[i].r) {
s[i].cnt = ;
s[i].numseg = ;
s[i].lc = s[i].rc = false;
}
else {
s[i].cnt = s[i<<].cnt + s[(i<<)|].cnt;
s[i].lc = s[i<<].lc;
s[i].rc = s[(i<<)|].rc;
s[i].numseg = s[i<<].numseg + s[(i<<)|].numseg;
if(s[i<<].rc&&s[(i<<)|].lc) s[i].numseg--;
}
} void update(int i,ll e) {
if(s[i].lf == e.x1 && s[i].rf == e.x2) {
s[i].c += e.f;
calen(i);
return ;
}
if(e.x2 <= s[i<<].rf) update(i << ,e);
else if(e.x1 >= s[(i<<)|].lf) update((i<<) | ,e);
else {
ll temp = e;
temp.x2 = s[i<<].rf;
update(i << ,temp);
temp = e;
temp.x1 = s[i<<|].lf;
update((i<<)|,temp);
}
calen(i);
} int main()
{
int x1,y1,x2,y2;
int n;
while(scanf("%d",&n) == ) {
int t = ;
for(int i = ;i < n; i++) {
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
l[t].x1 = x1;
l[t].x2 = x2;
l[t].y = y1;
l[t].f = ;
x[t++] = x1;
l[t].x1 = x1;
l[t].x2 = x2;
l[t].y = y2;
l[t].f = -;
x[t++] = x2;
}
sort(l,l+t,cmp);
sort(x,x+t);
int m = unique(x,x+t) - x;
build(,,m-);
int ans = ;
int last = ;
for(int i = ;i < t - ; i++) {
update(,l[i]);
ans += s[].numseg * * (l[i+].y - l[i].y);
ans += abs(s[].cnt - last);
last = s[].cnt;
}
update(,l[t-]);
ans += abs(s[].cnt - last);
printf("%d\n",ans);
}
return ;
}
POJ 1177 Picture(线段树 扫描线 离散化 求矩形并面积)的更多相关文章
- poj 1177 Picture (线段树 扫描线 离散化 矩形周长并)
题目链接 题意:给出n个矩形,每个矩形给左下 和 右上的坐标,求围成的周长的长度. 分析: 首先感谢大神的博客,最近做题经常看大神的博客:http://www.cnblogs.com/kuangbin ...
- poj 1177 --- Picture(线段树+扫描线 求矩形并的周长)
题目链接 Description A number of rectangular posters, photographs and other pictures of the same shape a ...
- 覆盖的面积 HDU - 1255 线段树+扫描线+离散化 求特定交叉面积
#include<cstdio> #include<map> #include<algorithm> using namespace std; ; struct N ...
- HDU 1828 / POJ 1177 Picture --线段树求矩形周长并
题意:给n个矩形,求矩形周长并 解法:跟求矩形面积并差不多,不过线段树节点记录的为: len: 此区间线段长度 cover: 此区间是否被整个覆盖 lmark,rmark: 此区间左右端点是否被覆盖 ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- hdu1255 覆盖的面积 线段树+里离散化求矩形面积的交
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 求矩形面积的交的线段树题目,刚做了求并的题目,再做这个刚觉良好啊,只要再加一个表示覆盖次数大于1 ...
- Picture POJ - 1177 (线段树-扫描线)
A number of rectangular posters, photographs and other pictures of the same shape are pasted on a wa ...
- POJ 1177 Picture(线段树周长并)
描述 A number of rectangular posters, photographs and other pictures of the same shape are pasted on ...
- hdu1542 Atlantis (线段树+扫描线+离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
随机推荐
- VirtualBox 虚拟Ubuntu系统与主机互ping
互ping的前提是主机和虚拟机的ip地址在同一波段[eg:主机为:192.168.1.10虚拟Linux:192.168.1.11] 1.设置主机ip: ...
- iOS 相似淘宝商品详情查看翻页效果的实现
基本思路: 1.设置一个 UIScrollView 作为视图底层,而且设置分页为两页 2.然后在第一个分页上加入一个 UITableView 而且设置表格可以上提载入(上拉操作即为让视图滚动到下一页) ...
- 初识Restful(学习笔记)
什么是Restful? REST -- Resource Representational State Transfer(表现层状态转移) 本质上是一种优雅的URL表达方式,描述资源的状态和状态的转移 ...
- LeetCode之16----3Sums Closest
题目: Given an array S of n integers, find three integers in S such that the sum is closest to a given ...
- Struts错误信息回传
<td height="20" align="center" class="loginMiddleDiv_loginInfo_window_wa ...
- #1241 : Best Route in a Grid
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个N行N列的非负整数方阵,从左上角(1,1)出发,只能向下或向右走,且不能到达值为0的方格,求出一条到达右下角的最佳 ...
- Easy smart REST with kbmMW
使用新版kbmMW开发的 smart service,也可以轻松的发布为通过REST来调用的功能. 一个 kbmMW smart service象下面这样实现,就可以使用REST来访问: ty ...
- HDU3533 Escape —— BFS / A*算法 + 预处理
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533 Escape Time Limit: 20000/10000 MS (Java/Others) ...
- CentOS7 安装jdk8
1.下载jdk8 jdk-8u162-linux-x64.tar.gz 2.解压 tar -vxf jdk-8u162-linux-x64.tar.gz 3.进入 jdk1.8.0_162 文件夹 终 ...
- poj 2771 Guardian of Decency(最大独立数)
题意:人与人之间满足4个条件之一即不能成为一对(也就说这4个条件都不满足才能成为一对),求可能的最多的单身人数. 思路:把男女分为两部分,接下来就是二分图的匹配问题.把能成为一对的之间连边,然后求出最 ...