Problem
acm.hdu.edu.cn/showproblem.php?pid=1542
Meaning
给出若干个平面上的矩形,问总的面积(重叠部分算一次)
Analysis
扫描线求矩形面积并。
算法中的离散化的一个作用是:将连续的实数坐标转成离散的整数(处理浮点数),从而可以用线段树来维护。
这篇是从左到右扫(从下往上扫看上篇)
Code
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100;
struct seg
{
double l, h, x;
int v;
seg() {}
seg(double _l, double _h, double _x, int _v):
l(_l), h(_h), x(_x), v(_v) {}
bool operator < (const seg &rhs) const
{
return x < rhs.x;
}
} s[N<<1];
int cvr[N<<3];
double y[N<<1], len[N<<3];
void pushup(int l, int r, int rt)
{
if(cvr[rt])
len[rt] = y[r] - y[l];
else if(l + 1 >= r)
len[rt] = 0.0;
else
len[rt] = len[rt<<1] + len[rt<<1|1];
}
void update(int ul, int ur, int v, int l, int r, int rt)
{
if(ul <= l && r <= ur)
{
cvr[rt] += v;
pushup(l, r, rt);
return;
}
int m = l + r >> 1;
if(ul < m)
update(ul, ur, v, l, m, rt<<1);
if(ur > m)
update(ul, ur, v, m, r, rt<<1|1);
pushup(l, r, rt);
}
int main()
{
for(int kase = 1, n; scanf("%d", &n), n; ++kase)
{
for(int i = 0; i < n; ++i)
{
double xl, xr, yl, yr;
scanf("%lf%lf%lf%lf", &xl, &yl, &xr, &yr);
s[i] = seg(yl, yr, xl, 1);
s[i+n] = seg(yl, yr, xr, -1);
y[i] = yl;
y[i+n] = yr;
}
n <<= 1;
sort(s, s + n);
sort(y, y + n);
int m = unique(y, y + n) - y;
memset(cvr, 0, sizeof cvr);
memset(len, 0, sizeof len);
double ans = 0.0;
for(int i = 0, l, h; i < n - 1; ++i)
{
l = lower_bound(y, y + m, s[i].l) - y;
h = lower_bound(y, y + m, s[i].h) - y;
update(l, h, s[i].v, 0, m-1, 1);
ans += len[1] * (s[i+1].x - s[i].x);
}
printf("Test case #%d\nTotal explored area: %.2f\n\n", kase, ans);
}
return 0;
}