题目大意:
给出一个平面内N个矩形的左下角顶点(x1,y1)及右上角顶点(x2,y2)
给
出
一
个
平
面
内
N
个
矩
形
的
左
下
角
顶
点
(
x
1
,
y
1
)
及
右
上
角
顶
点
(
x
2
,
y
2
)
问它们在平面中占的总面积是多少。
问
它
们
在
平
面
中
占
的
总
面
积
是
多
少
。
1≤N≤100
1
≤
N
≤
100
0<=x1<x2<=100000;0<=y1<y2<=100000
0
<=
x
1
<
x
2
<=
100000
;
0
<=
y
1
<
y
2
<=
100000
分析:
可以采用扫描线
O(n2)
O
(
n
2
)
的实现,
也可以通过线段树对扫描线进行优化,
达到
O(nlogn)
O
(
n
l
o
g
n
)
扫描线的几篇详细blog
https://blog.csdn.net/otowa/article/details/50695401
这题还要注意一下对
xi
x
i
进行离散
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 205
#define eps 1e-6
using namespace std;
struct Node {
double l, r, h;
int add;
}c[N];
struct Note {
int l, r, p;
double sum;
}a[5 * N];
double x[N];
bool cmp(Node aa, Node bb) {
return aa.h < bb.h;
}
void Build_tree(int G, int l, int r) {
a[G].l = l, a[G].r = r;
a[G].sum = a[G].p = 0;
if (l == r) return;
int mid = (l + r) >> 1;
Build_tree(G * 2, l, mid);
Build_tree(G * 2 + 1, mid + 1, r);
}
int Get_id(double num, int l, int r) {
while (l <= r) {
int mid = (l + r) >> 1;
if (fabs(x[mid] - num) <= eps) return mid;
if (x[mid] < num) l = mid + 1;
else r = mid - 1;
}
return l;
}
double Get_sum(int G) {
if (a[G].p) return x[a[G].r + 1] - x[a[G].l];
return a[G * 2].sum + a[G * 2 + 1].sum;
}
void Insert_tree(int G, int x1, int x2, int add) {
if (a[G].l == x1 && a[G].r == x2) {
a[G].p += add;
a[G].sum = Get_sum(G);
return;
}
int mid = (a[G].l + a[G].r) >> 1;
if (x2 <= mid) Insert_tree(G * 2, x1, x2, add);
else if (x1 > mid) Insert_tree(G * 2 + 1, x1, x2, add);
else {
Insert_tree(G * 2, x1, mid, add);
Insert_tree(G * 2 + 1, mid + 1, x2, add);
}
a[G].sum = Get_sum(G);
}
int main() {
double x1, y1, x2, y2, ans;
int n, tot, Case = 0;
while (~scanf("%d", &n) && n) {
tot = 0;
for (int i = 1; i <= n; i++) {
scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
x[++tot] = x1, c[tot].l = x1, c[tot].r = x2, c[tot].h = y1, c[tot].add = 1;
x[++tot] = x2, c[tot].l = x1, c[tot].r = x2, c[tot].h = y2, c[tot].add = -1;
}
sort(c + 1, c + tot + 1, cmp);
sort(x + 1, x + tot + 1);
int cnt = 1;
for (int i = 2; i <= tot; i++)
if (x[i] != x[i - 1]) x[++cnt] = x[i];
ans = 0;
Build_tree(1, 1, cnt - 1);
for (int i = 1; i < tot; i++) {
int x1 = Get_id(c[i].l, 1, cnt);
int x2 = Get_id(c[i].r, 1, cnt) - 1;
if (x1 <= x2) Insert_tree(1, x1, x2, c[i].add);
ans += (c[i + 1].h - c[i].h) * a[1].sum;
}
printf("Test case #%d\n", ++Case);
printf("Total explored area: %.2f\n\n", ans);
}
return 0;
}