poj 1151 Atlantis(计算几何 扫描线)

来源:互联网 发布:如何找到淘宝上的假货 编辑:程序博客网 时间:2024/05/22 14:12

题目链接:http://poj.org/problem?id=1151

大致题意:给出n个矩形,求出n个矩形一共覆盖的面积

做法:现将坐标离散化,然后用线段树维护

即让线段按照x坐标的大小从小到大排列,y坐标按照从小到大排列去掉重复的值

然后通过一个扫描线来求扫描线覆盖的y的长度。

线段的扫描按照x的大小从小到大扫描,求出当前扫描线覆盖的矩阵竖线的长度,然后乘以下条线段的跨度,则为这个区域矩阵覆盖的面积

其实,还是我柴的板硬。。。。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define MAXN 220struct Node{    int l, r;    int c;    double cnt, lf, rf;} segTree[MAXN*3];struct Line{    double x, y1, y2;    int f;} line[MAXN];bool cmp(Line a, Line b){    return a.x < b.x;}double y[MAXN];void Build(int t, int l, int r){    segTree[t].l = l;    segTree[t].r = r;    segTree[t].cnt = segTree[t].c = 0;    segTree[t].lf = y[l];    segTree[t].rf = y[r];    if(l + 1 == r) return ;    int mid = (l+r) >> 1;    Build(t<<1, l, mid);    Build(t<<1|1, mid, r);}void calen(int t){    if(segTree[t].c > 0)    {        segTree[t].cnt = segTree[t].rf - segTree[t].lf;        return ;    }    if(segTree[t].l+1 == segTree[t].r)        segTree[t].cnt = 0;    else        segTree[t].cnt = segTree[t<<1].cnt + segTree[t<<1|1].cnt;}void update(int t, Line e){    if(e.y1 == segTree[t].lf && e.y2 == segTree[t].rf)    {        segTree[t].c += e.f;        calen(t);        return ;    }    if(e.y2 <= segTree[t<<1].rf)        update(t<<1, e);    else if(e.y1 >= segTree[t<<1|1].lf)        update(t<<1|1, e);    else    {        Line tmp = e;        tmp.y2 = segTree[t<<1].rf;        update(t<<1, tmp);        tmp = e;        tmp.y1 = segTree[t<<1|1].lf;        update(t<<1|1, tmp);    }    calen(t);}int main(){    int i, n, t, cas = 0;    double x1, x2, y1, y2;    while(cin>>n && n)    {        t = 1;        for(int i=1; i<=n; i++)        {            cin>>x1>>y1>>x2>>y2;            line[t].x = x1, line[t].y1 = y1;            line[t].y2 = y2, line[t].f = 1;            y[t++] = y1;            line[t].x = x2, line[t].y1 = y1;            line[t].y2 = y2, line[t].f = -1;            y[t++] = y2;        }        sort(line+1, line+t, cmp);        sort(y+1, y+t);        Build(1,1,t-1);        update(1, line[1]);        double res = 0;        for(int i=2; i<t; i++)        {            res += segTree[1].cnt * (line[i].x - line[i-1].x);            update(1, line[i]);        }        printf("Test case #%d\nTotal explored area: %.2f\n\n",++cas, res);    }    return 0;}



1 0
原创粉丝点击