算法学习之——矩形切割思想
2014-11-19 13:17
246 查看
算法学习之——矩形切割思想
MPS
【定义 Define】
对于求解若干个矩形的面积的交集,而且又必须是O(NlogN)以内的,往往采用矩形切割思想
说白了,其实就是给你若干个矩形,让你求任意一个矩形不被覆盖的面积总和
【处理方法】
类似下图:(图片出处:http://www.cppblog.com/xiongnanbin/articles/90805.html?opt=admin)
我们假设有2个矩形:A和B,A用白色染色,B用黄色染色,A放在底层,B放在A之上,这样,黄色区域就是矩形A和矩形B的交集了,我们可以发现
wx1=max(wx1,x1)
wx2=min(wx2,x2)
wy1=max(wy1,y1)
wy2=min(wy2,y2)
这样,我们判断是否存在,不存在则没有,结束,否则继续上浮,寻找下一个重叠矩阵
【例题】
(转载自:USACO)
Shaping Regions
形成的区域
译 by tim green
N个不同的颜色的不透明的长方形(1 <= N <= 1000)被放置在一张宽为A长为B的白纸上。
这些长方形被放置时,保证了它们的边于白纸的边缘平行。
所有的长方形都放置在白纸内,所以我们会看到不同形状的各种颜色。
坐标系统的原点(0,0)设在这张白纸的左下角,而坐标轴则平行于边缘。
PROGRAM NAME: rect1
INPUT FORMAT
每行输入的是放置长方形的方法。
第一行输入的是那个放在底的长方形(即白纸)。
SAMPLE INPUT (file rect1.in)
20 20 3
2 2 18 18 2
0 8 19 19 3
8 0 10 19 4
OUTPUT FORMAT
输出文件应该包含一个所有能被看到颜色连同该颜色的总面积的清单( 即使颜色的区域不是连续的),按color的增序顺序。
不要显示没有区域的颜色。
SAMPLE OUTPUT (file rect1.out)
1 91
2 84
3 187
4 38
这题网上有三种做法,第一种是二维线段树(难度太高,空间不足,忽略)第二种是矩形树(忽略)第三种就是矩形切割算法
我们同样染色(题目要求),然后直接就交集即可
MPS
【定义 Define】
对于求解若干个矩形的面积的交集,而且又必须是O(NlogN)以内的,往往采用矩形切割思想
说白了,其实就是给你若干个矩形,让你求任意一个矩形不被覆盖的面积总和
【处理方法】
类似下图:(图片出处:http://www.cppblog.com/xiongnanbin/articles/90805.html?opt=admin)
我们假设有2个矩形:A和B,A用白色染色,B用黄色染色,A放在底层,B放在A之上,这样,黄色区域就是矩形A和矩形B的交集了,我们可以发现
wx1=max(wx1,x1)
wx2=min(wx2,x2)
wy1=max(wy1,y1)
wy2=min(wy2,y2)
这样,我们判断是否存在,不存在则没有,结束,否则继续上浮,寻找下一个重叠矩阵
【例题】
(转载自:USACO)
Shaping Regions
形成的区域
译 by tim green
N个不同的颜色的不透明的长方形(1 <= N <= 1000)被放置在一张宽为A长为B的白纸上。
这些长方形被放置时,保证了它们的边于白纸的边缘平行。
所有的长方形都放置在白纸内,所以我们会看到不同形状的各种颜色。
坐标系统的原点(0,0)设在这张白纸的左下角,而坐标轴则平行于边缘。
PROGRAM NAME: rect1
INPUT FORMAT
每行输入的是放置长方形的方法。
第一行输入的是那个放在底的长方形(即白纸)。
第 1 行: | A , B 和 N, 由空格分开 (1 <=A, B<=10,000) |
第 2 到N+1行: | 为五个整数 llx, lly, urx, ury, color 这是一个长方形的左下角坐标,右上角坐标和颜色(1<=color<=2500)。 颜色 1和底部白纸的颜色相同。 |
20 20 3
2 2 18 18 2
0 8 19 19 3
8 0 10 19 4
OUTPUT FORMAT
输出文件应该包含一个所有能被看到颜色连同该颜色的总面积的清单( 即使颜色的区域不是连续的),按color的增序顺序。
不要显示没有区域的颜色。
SAMPLE OUTPUT (file rect1.out)
1 91
2 84
3 187
4 38
这题网上有三种做法,第一种是二维线段树(难度太高,空间不足,忽略)第二种是矩形树(忽略)第三种就是矩形切割算法
我们同样染色(题目要求),然后直接就交集即可
#include <iostream> #include <cstdio> #include <algorithm> #include <cctype> #include <cstring> #include <string> #include <cstdlib> #include <vector> #include <queue> #include <deque> using namespace std; const int MaxN=10001; const int MAXN=2500; int x1[MaxN],y1[MaxN],x2[MaxN],y2[MaxN],n,m,c; int color[MaxN],area[MaxN]; int now;//当前矩形的颜色 //矩形切割思想 void solve(int l,int r,int b,int t,int z){ while(z<=c && (l>=x2[z] || r<=x1[z] || b>=y2[z] || t<=y1[z]))z++; if(z>c){//没有重叠 area[now]+=(r-l)*(t-b); return; } if(l<x1[z])//右上角重叠 { solve(l,x1[z],b,t,z+1); l=x1[z]; } if(r>x2[z]){ solve(x2[z],r,b,t,z+1); r=x2[z]; } if(b<y1[z])solve(l,r,b,y1[z],z+1); if(t>y2[z])solve(l,r,y2[z],t,z+1); } int main(){ scanf("%d%d%d",&n,&m,&c); int i; x1[0]=y1[0]=0;x2[0]=n;y2[0]=m;color[0]=1; for(i=1;i<=c;i++)scanf("%d%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i],&color[i]); memset(area,0,sizeof(area)); for(i=c;i>=0;i--){ now=color[i]; solve(x1[i],x2[i],y1[i],y2[i],i+1); } for(i=1;i<=MAXN;i++) if(area[i])printf("%d %d\n",i,area[i]); return 0; }
相关文章推荐
- 算法设计和数据结构学习_2(常见排序算法思想)
- 机器学习十大算法的每个算法的核心思想、工作原理、适用情况及优缺点
- 动态规划学习(一)算法思想简介
- 深度学习前沿算法思想
- 深度增强学习前沿算法思想
- 线段树思想实现矩形切割
- 算法设计和数据结构学习_2(常见排序算法思想)
- 深度增强学习前沿算法思想
- 【算法学习】切割木棍问题——动态规划
- 深度增强学习前沿算法思想
- 本文专注于<递归算法和分治思想>[胖虎学习算法系列]
- 数据结构与算法学习之路:迷宫问题——回溯思想找出所有路径
- 数据结构与算法学习之路:LIS——最长递增序列的动态规划算法和二分思想算法
- 【算法学习】归并排序——基于分治思想
- 数据结构之图论算法伪代码(伪代码是一种思想可对照伪代码的实用代码学习算法设计)
- 算法学习笔记----用动态规划解决钢管切割问题
- 算法设计和数据结构学习_1(常见排序算法思想)
- 【算法之动态规划(五)】DP规划思想学习:从《算法导论》到《算法设计》
- 深度增强学习前沿算法思想【DQN、A3C、UNREAL,简介】
- 算法思想学习系列:分治法——求数列的逆序数