扫描线的模板题,先把信息接收,然后排序,记录下上边和下边,然后用一条虚拟的线从下往上扫。如果我扫到的是下边,那么久用线段树在这个区间内加上1,表示这个区间现在是有的,等我扫描到上边的时候在加上-1,把之前的消掉,然后线段树维护区间内的长度,这里不是直接用下标维护,而是需要另一个数组来维护,每次记录我当前的下标在原本的图中的长度。
在update部分用一个点表示我这个点以后的一个长度为1的区间,然后这样算出来的sum[1]就是我现在线段树里包括的区间大小,然后用现在的区间大小去乘上这一部分的高度,然后每次相加,就可以了
#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x & (-x))
typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 305;
const int maxm = 305;
using namespace std;
int n, m, tol, T;
struct Node {
double l, r, h;
int f;
bool operator <(Node a) const {
return h < a.h;
}
};
Node node[maxn];
double a[maxn];
double sum[maxn << 2];
int cnt[maxn << 2];
void init() {
memset(sum, 0, sizeof sum);
memset(cnt, 0, sizeof cnt);
}
void pushup(int left, int right, int root) {
if(cnt[root] != 0) sum[root] = a[right + 1] - a[left];
else if(left == right) sum[root] = 0;
else sum[root] = sum[root << 1] + sum[root << 1 | 1];
}
void update(int left, int right, int prel, int prer, int val, int root) {
if(prel <= left && right <= prer) {
cnt[root] += val;
pushup(left, right, root);
return ;
}
int mid = (left + right) >> 1;
if(prel <= mid) update(left, mid, prel, prer, val, root << 1);
if(prer > mid) update(mid+1, right, prel, prer, val, root << 1 | 1);
pushup(left, right, root);
}
int main() {
int cas = 1;
while(scanf("%d", &n)== 1 && n) {
init();
double x1, y1, x2, y2;
for(int i=1; i<=n; i++) {
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
node[2*i-1].l = x1;
node[2*i].l = x1;
node[2*i-1].r = x2;
node[2*i].r = x2;
node[2*i-1].h = y1;
node[2*i].h = y2;
node[2*i-1].f = 1;
node[2*i].f = -1;
a[2*i-1] = x1;
a[2*i] = x2;
}
n = 2*n;
sort(node+1, node+1+n);
sort(a+1, a+1+n);
int nn = unique(a+1, a+1+n) - (a+1);
double ans = 0;
for(int i=1; i<n; i++) {
int l = lower_bound(a+1, a+1+nn, node[i].l) - a;
int r = lower_bound(a+1, a+1+nn, node[i].r) - a;
update(1, nn, l, r-1, node[i].f, 1);
ans += (node[i+1].h - node[i].h) * sum[1];
}
printf("Test case #%d\n", cas++);
printf("Total explored area: %0.2f\n", ans);
printf("\n");
}
return 0;
}
来源:oschina
链接:https://my.oschina.net/u/4406323/blog/3894704