POJ 1151

来源:互联网 发布:java内存泄露例子 编辑:程序博客网 时间:2024/05/16 10:06
思路:首先将横坐标离散化,再对纵坐标排序,然后根据y轴从下往上扫描,每次的高度就是seg[i].y-seg[i-1].y,这就相当于分矩形的宽,然后要做的事就是查询x轴(矩形长)的有效长度,这就要交给线段树了。

/*************************************************************************    > File Name:        area.cpp    > Author:         wangzhili    > Mail:           wangstdio.h@gmail.com    > Created Time:   2014/3/1 星期六 16:06:57 ************************************************************************/#include<iostream>#include<algorithm>#include<cstdio>#define MAX 1000using namespace std; class TreeNode{    public:        int left;         int right;        int mid;         int cover;         int flag;        double length;  }; typedef struct{    double xl, xr, y;     int flag; }Line; TreeNode node[3*MAX]; Line seg[MAX];double x[MAX]; double length;bool cmp(Line a, Line b){    return a.y < b.y; }void BuildTree(int k, int l, int r){    node[k].left = l;     node[k].right = r;     node[k].mid = (l + r) >> 1;     node[k].cover = 0;     node[k].flag = 0;     if(l + 1 == r)    {        node[k].flag = 1;         return ;     }    int mid = (l + r) >> 1;     BuildTree(k << 1, l, mid);     BuildTree(k << 1|1, mid, r); }void UpdateTree(int k, int l, int r, int flag){    if(node[k].left == l && node[k].right == r)    {        node[k].cover += flag;         node[k].length = x[r-1] - x[l-1];          return ;     }    if(node[k].flag)        return ;     if(node[k].mid <= l)        UpdateTree(k << 1|1, l, r, flag);     else if(node[k].mid >= r)        UpdateTree(k << 1, l, r, flag);     else    {        UpdateTree(k << 1, l, node[k].mid, flag);         UpdateTree(k << 1|1, node[k].mid, r, flag);     }}void GetLength(int k){    if(node[k].cover > 0)    {        length += node[k].length;          return ;     }    if(node[k].flag)        return;     GetLength(k << 1);     GetLength(k << 1|1); }int GetIndex(double num, int length){    int l, r, mid;     l = 0, r = length-1;     while(l <= r)    {        mid = (l + r) >> 1;         if(x[mid] == num)            return mid;         else if(x[mid] > num)            r = mid - 1;         else            l = mid + 1;     }}int main(int argc, char const *argv[]) {    int n, i, j, k, cnt;     int xl, xr;     double ans;     double x1, y1, x2, y2;    cnt = 0;     BuildTree(1, 1, 205);    // freopen("in.c", "r", stdin);     while(~scanf("%d", &n) && n)    {        j = 0;         ans = 0.;         for(i = 1; i < 408; i ++)        {            node[i].cover = 0;         }        for(i = 0; i < n; i ++)        {            scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);             seg[j].xl = x1;             seg[j].xr = x2;             seg[j].y = y1;             x[j] = x1;             seg[j ++].flag = 1;             seg[j].xl = x1;             seg[j].xr = x2;             seg[j].y = y2;             x[j] = x2;             seg[j ++].flag = -1;         }        sort(x, x+j);         sort(seg, seg+j, cmp);         k = 1;         for(i = 1; i < j; i ++)        {            if(x[i] != x[i-1])                x[k ++] = x[i];         }        xl = GetIndex(seg[0].xl, k) + 1;         xr = GetIndex(seg[0].xr, k) + 1;         UpdateTree(1, xl, xr, seg[0].flag);         length = 0;         GetLength(1);         for(i = 1; i < j; i ++)        {            ans += (seg[i].y-seg[i-1].y)*length;             xl = GetIndex(seg[i].xl, k)+1;             xr = GetIndex(seg[i].xr, k)+1;             UpdateTree(1, xl, xr, seg[i].flag);             length = 0.;             GetLength(1);         }        printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++cnt, ans);     }    return 0; }


                                             
0 0