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 ...
随机推荐
- [游戏]L4D求生之路官方比赛地图修补完好说明
游戏模式:L4D求生之路4356(1.0.2.1)药抗比赛模式 更新日期:2015.06.04 -----毫不留情01----- 1.开局补给手枪 -----毫不留情02----- 1.开局补给手枪 ...
- Posix信号量操作函数
Posix信号量: 分类: Posix有名信号量:使用Posix IPC名字标识,可用于线程或进程间同步Posix基于内存的信号量:存放在共享内存区中,可用于进程或线程间的同步 sem_open(). ...
- Linux安装Axis C构建WebService服务
在安装Axis C++之前有两个组件是必须安装的,分别是Apache HTTP Server以及用于处理XML的程序Xerces:为了编译Axis以及Apache HTTPD,你的Linux机器还应该 ...
- Appium,IOS 模拟器,Java工程搭建
首先进入sample code Test App 有TestApp.xcodeproj文件的工程目录下 下编译出TestApp.app文件 1.新建 java 工程 2.import需要的包 新建cl ...
- ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column XXX at row 1
本错误为:该列的插入格式有误 修改该表中该列的字符集为utf-8 网上办法: )不能插入中文解决办法: 向表中插入中文然后有错误. mysql> insert into users values ...
- 正则表达式pattern的匹配格式
0> 匹配 -------------------------------------------------------------------------------- (pattern) ...
- java map 装入list
需要生成多组数据的时候,应将map时候放入循环,否则循环出来会一直覆盖之前的,只能保存一条数据. 具体如下: if (rs.next()) { do { Map<String, String&g ...
- React在Render中使用bind可能导致的问题
因为bind在render的时候会重现生成,这样会导致props每次都不同, puremixin的插件也会失效. 所以需要将bind的结果缓存下来,或者直接在constructor里做这个事情 con ...
- react native 知识点总结(一)
一.关于react native 版本的升级 参照文档:http://reactnative.cn/docs/0.45/upgrading.html react-native -v 查看当前版本 ...
- MyEclipse注释配置
MyEclipse注释配置 配置路径 1.1. JAVA 打开MyEclipse,选择Window>Preferences>Java>Code Style>Code ...