矩形面积求并 扫描线

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 333 + 1;
double w[maxn]; int  A[maxn], rank1[maxn], B[maxn]; double sumv[maxn * 5], idx[maxn * 5];
struct R { double  min, max; }node[maxn];
struct E { int l, r; double h;int v; }Edge[maxn];
int cmp(const int i, const int j) { return w[i] < w[j]; }
int cmp2(const int i, const int j) { return Edge[i].h < Edge[j].h; }
void Update(int o, int L, int R) {
	if (idx[o])sumv[o] = w[A[R]] - w[A[L]];
	else if (L == R)sumv[o] = 0;
	else sumv[o] = sumv[o * 2] + sumv[o * 2 + 1];
}
void update(int l, int r, int L, int R, int o, int v) {
	if (l <= L&&r >= R)
	{
		idx[o] += v;
		Update(o, L, R);
		return;
	}
	int mid = (L + R) / 2;
	if (l < mid)update(l, r, L, mid, o * 2, v);
	if (r > mid)update(l, r, mid, R, o * 2 + 1, v);
	Update(o, L, R);
}
int main() {
	int N;
	int css = 0;
	while (++css) {
		scanf("%d", &N); if (!N)return 0;
		memset(w, 0, sizeof(w)); memset(A, 0, sizeof(A)); memset(rank1, 0, sizeof(rank1)); memset(B, 0, sizeof(B)); memset(sumv, 0, sizeof(sumv));
		memset(idx, 0, sizeof(idx)); memset(Edge, 0, sizeof(Edge)); memset(node, 0, sizeof(node));
		double ans = 0;
		for (int i = 1; i <= N; ++i) {
			double a, b, c, d;
			scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
			w[i * 2 - 1] = a, w[i * 2] = c;
			node[i].min = b, node[i].max = d;
		}
		for (int i = 1; i <= 2 * N; ++i)A[i] = i;
		sort(A + 1, A + 1 + N + N, cmp);
		int u = 1; rank1[A[1]] = 1;
		for (int i = 2; i <= 2 * N; ++i)if (w[A[i]] != w[A[i - 1]])rank1[A[i]] = ++u;
		else rank1[A[i]] = rank1[A[i - 1]];
		for (int i = 1; i <= N; ++i) {
			Edge[i * 2 - 1].l = Edge[i * 2].l = rank1[i * 2 - 1];
			Edge[i * 2 - 1].r = Edge[i * 2].r = rank1[i * 2];
			Edge[i * 2 - 1].h = node[i].min, Edge[i * 2].h = node[i].max;
			Edge[i * 2 - 1].v = 1, Edge[i * 2].v = -1;
		}
		int y = 1;
		for (int i = 2; i <= 2 * N; ++i) if (w[A[i]] != w[A[i - 1]])A[++y] = A[i];
		for (int i = 1; i <= 2 * N; ++i)B[i] = i;
		sort(B + 1, B + 1 + N + N, cmp2);
		for (int i = 1; i <= 2 * N; ++i) {
			update(Edge[B[i]].l, Edge[B[i]].r, 1, 300, 1, Edge[B[i]].v);
			ans += (Edge[B[i + 1]].h - Edge[B[i]].h)*sumv[1];
		}
		printf("Test case #%d\nTotal explored area: %.2f\n\n", css, ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liyong1009s/article/details/83099604