A

来源:互联网 发布:游族网络大皇帝礼包 编辑:程序博客网 时间:2024/06/10 12:12

题意

给定多个矩形,会出现重叠的情况,问总面积是多少?

解法

采用了线段树+扫描线的做法,

一些小技巧

  1. 离散化: 先用sort进行需要离散的数据排须,然后用unique进行去重复。
    unique()函数的参数和sort函数一致,将重复的元素放到数组的最后面,返回值是最后一个unique的数地址+1。
  2. 这里面有个很莫名其妙的部分就是update的时候r要先减1,之后在进行区间长度计算的时候r再加回来,如果不进行这样的处理,会出现没法计算区间长度的情况。
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>using namespace std;const int maxn = 100 + 10;struct segment{    double l, r, h;    int f;}segments[2 * maxn];int n, sn, pos_num, coverv[2 * 4 * maxn];double pos[2 * maxn],lenv[2 * 4 * maxn];int cmp(segment a, segment b){    if(a.h < b.h) return 1;    else return 0;}void maintain(int o, int L, int R){    if(coverv[o]) lenv[o] = pos[R + 1] - pos[L];    else if(L == R){        lenv[o] = 0;    }    else lenv[o] = lenv[o << 1] + lenv[o << 1 | 1];}void update(int o, int l, int r, int L, int R, int v){    if(l <= L && r >= R){        coverv[o] += v;    }    else{        int M = L + (R - L) / 2;        if(l <= M) update(o << 1, l, r, L, M, v);        if(r > M) update(o << 1 | 1, l, r, M + 1, R, v);    }    maintain(o, L, R);}int main(){    //freopen("input.txt", "r", stdin);    int t = 0;    while(scanf("%d", &n) != EOF){        if(n == 0) break;        t ++;        printf("Test case #%d\n", t);        printf("Total explored area: ");        memset(pos, 0, sizeof(pos));        memset(coverv, 0, sizeof(coverv));        memset(lenv, 0, sizeof(lenv));        sn = 0;        pos_num = 0;        for(int i = 1; i <= n; i++){            double x1, y1, x2, y2;            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);            segments[sn].l = x1;            segments[sn].r = x2;            segments[sn].h = y1;            segments[sn].f = 1;            sn ++;            segments[sn].l = x1;            segments[sn].r = x2;            segments[sn].h = y2;            segments[sn].f = -1;            sn ++;            pos[pos_num++] = x1;            pos[pos_num++] = x2;        }        sort(pos, pos + pos_num);        sort(segments, segments + sn, cmp);        pos_num = unique(pos, pos + pos_num) - pos;        //cout << pos_num <<endl;        double ans = 0;        for(int i = 0; i < sn; i++){            int l = lower_bound(pos, pos + pos_num, segments[i].l) - pos;            int r = lower_bound(pos, pos + pos_num, segments[i].r) - pos -1;            //cout << l << r << endl;            update(1, l, r, 0, pos_num - 1, segments[i].f);            //cout << lenv[1] <<"("<< lenv[2] <<","<<lenv[3]<<")" << " " << (segments[i+1].h - segments[i].h) << endl;            ans += lenv[1] * (segments[i+1].h - segments[i].h);        }        printf("%.2lf\n\n", ans);    }    return 0;}
原创粉丝点击