前言
扫描线应该是一个很有用的算法。
它有许多用途,比较经典的应该就是用来求矩形面积并。
什么是矩形面积并
或许你会问,什么是矩形面积并?
在一个平面上,有若干个矩形,它们覆盖的总面积就是矩形面积并(重叠部分只算一次)。
要求矩形面积并,我们就可以用扫描线。
离散化
首先,我们要将这张图离散化预处理一下。
离散化的过程应该比较简单,将每个节点的坐标全部存在一个数组中,排序+去重之后,就形成了一个离散化之后的数组,把它们加入一个 m a p map map中即可(或直接二分)。
代码如下:
for(i=1;i<=n;++i) cin>>x1>>y1>>x2>>y2,xy[(i<<2)-3]=x1,xy[(i<<2)-2]=y1,xy[(i<<2)-1]=y2,xy[i<<2]=x2;//将每一个点的坐标全部存在一个数组中
sort(xy+1,xy+(n<<2)+1);//排序
for(i=1;i<=n<<2;++i)//枚举每一个值
if(!p[xy[i]]) f[p[xy[i]]=++cnt]=xy[i];//p存储离散化后的值,f存储原来的值,需去重
如何存储一个矩形
接下来,我们要考虑如何存储一个读入的矩形。
不难发现,其实我们只需要记录每个矩形的左右两条边即可,其中一条标记为正,一条标记为负,表示开始与结束。
代码如下:
struct Square//一个结构体
{
int flag,nx,ny1,ny2;//flag记录这条边的类型(1或-1,分别表示开始与结束),nx,ny1,ny2分别存储x,y1,y2离散化后的值
double x,y1,y2;//x记录这条边x轴上的坐标,y1,y2分别记录这条边在y轴上的起点与终点
}a[2*N+5];
for(i=1;i<=n;++i) cin>>x1>>y1>>x2>>y2,a[(i<<1)-1]=(Square){
1,0,0,0,x1,y1,y2},a[i<<1]=(Square){
-1,0,0,0,x2,y1,y2};//读入并存储每一个矩形
//离散化的过程(见上)
for(i=1;i<=n<<1;++i)//将每条边的坐标更新为离散化后的坐标
a[i].nx=p[a[i].x],a[i].ny1=p[a[i].y1],a[i].ny2=p[a[i].y2]