求多边形面积并
就是说在二维平面上给你一堆多边形,然后求所有面积的并集,重叠的地方只算一次。就相当于一张桌子上随意放了一堆多边形,求占桌子的总面积。
求面积并问题一般用两种方法,扫描线和自适应辛普森积分。
扫描线
矩形面积并
就是从左到右,用一条条竖直的线将所有多边形按照竖直的边分成一个个小矩形,一般适用于各边都是直的多边形,例如矩形,三角形。具体一点可以看下图:
有四个黑色的矩形随机的放在一起,然后我们用这些红线从所有的矩形的竖直边将整个图分成若干长条,使得每个长条内没有矩形的竖直边。这些就是扫描线。这样操作之后,我们的面积并就好求了,只需要计算所有红线之间的小矩形面积即可。
小矩形的面积就是长乘宽,宽就是两条红线之间的距离。长就是所有在两条红线内的矩形的长的区间合并的总长。如图:
我们挨着求完所有红线之间的面积之和,就是所有的面积并了。
代码模板
原题链接:Acwing 3068. 扫描线
#include<iostream>
#include<vector>
#include<algorithm>
#define x first //方便使用pair
#define y second
using namespace std;
const int N = 1010;
typedef pair<int,int> PII; //用pair来存坐标,所有坐标都是整数
typedef long long LL; //答案要用long long存
int n;
LL ans; //答案
PII l[N],r[N],q[N]; //l存左下角的坐标,r存右上角的坐标,q记两条竖线之间的区间
vector<int> xs; //xs存所有矩形的竖直边
LL range_area(int a,int b) //计算竖直线x=a和x=b之间的面积
{
LL cnt = 0,res = 0; //cnt记两条竖线内的矩形个数,res记区间合并后的长度
for(int i = 0;i < n;i++) //循环所有矩形
if(l[i].x <= a && r[i].x >= b) //判断若矩形在区间内部
q[cnt++] = {
l[i].y,r[i].y}; //将该矩形竖直方向的区间存进q
if(!cnt) //如果cnt为0,说明该两条竖线之间没有矩形
return 0; //直接返回0
sort(q,q+cnt); //区间合并,先对q进行排序
int st = q[0].x, ed = q[0].y; //st和ed是当前区间的起点和终点
for(int i = 1;i < cnt;i++) //循环所有区间
{
if(q[i