poj1151

大概是扫描线的板子?。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 2e2 + 5;

struct LineH
{
    double lx, rx, y;
    int cover;
    LineH() {}
    LineH(double _lx, double _rx, double _y, int _cover):
        lx(_lx), rx(_rx), y(_y), cover(_cover) {}
};

LineH hor[MAXN * 2];
double discrete[MAXN * 2];
int n;

struct LineV
{
    int l, r;
    int cover;
    double cnt, lf, rf;
    LineV() {}
};
LineV ver[MAXN * 4];

bool cmp(LineH &a, LineH &b)
{
    return a.y < b.y;
}

void build(int root, int l, int r)
{
    ver[root].l = l;
    ver[root].r = r;
    ver[root].cnt = ver[root].cover = 0;
    ver[root].lf = discrete[l];
    ver[root].rf = discrete[r];
    if(r - l == 1) return;
    int mid = (l + r) / 2;
    build(root * 2, l, mid);
    build(root * 2 + 1, mid, r);
}

void calculate(int t)
{
    if(ver[t].cover > 0)
    {
        ver[t].cnt = ver[t].rf - ver[t].lf;
        return;
    }
    if(ver[t].r - ver[t].l == 1) ver[t].cnt = 0;
    else ver[t].cnt = ver[t * 2].cnt + ver[t * 2 + 1].cnt;
}

void update(int t, LineH &line)
{
    if(line.lx == ver[t].lf && line.rx == ver[t].rf)
    {
        ver[t].cover += line.cover;
        calculate(t);
        return;
    }
    if(line.rx <= ver[t * 2].rf) update(t * 2, line);
    else if(line.lx >= ver[t * 2 + 1].lf) update(t * 2 + 1, line);
    else
    {
        LineH temp = line;
        temp.rx = ver[t * 2].rf;
        update(t * 2, temp);
        temp = line;
        temp.lx = ver[t * 2 + 1].lf;
        update(t * 2 + 1, temp);
    }
    calculate(t);
}

int main()
{
    // freopen("in.txt", "r", stdin);
    int test_case = 0, total = 0;
    double x, y, z, w;
    while(scanf("%d", &n) && n != 0)
    {

        ++test_case;
        total = 0;
        for(int i = 1; i <= n; ++i)
        {
            scanf("%lf%lf%lf%lf", &x, &y, &z, &w);
            hor[++total] = LineH(x, z, y, 1);
            discrete[total] = x;
            hor[++total] = LineH(x, z, w, -1);
            discrete[total] = z;
        }
        sort(hor + 1, hor + 1 + total, cmp);
        sort(discrete + 1, discrete + 1 + total);
        build(1, 1, total);
        update(1, hor[1]);
        double ans = 0.0;
        for(int i = 2; i <= total; ++i)
        {
            ans += ver[1].cnt * (hor[i].y - hor[i - 1].y);
            update(1, hor[i]);
        }
        printf("Test case #%d\nTotal explored area: %.2f\n\n", test_case, ans);
    }
}