POJ 1151

原创 2016年07月31日 12:51:28
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

const double eps = 1e-8;
const int maxn = 310;
struct node{
    double len;
    int cover;
}tree[8*maxn];

struct scanline{
    double x, y1, y2;
    int cover;
    bool operator < (const scanline& another) const{
        return x < another.x;
    }
};

vector<scanline> scanline_vector;
double segment_point[2*maxn];

void build(int left, int right, int root,int layer){
    tree[root].cover = 0;
    tree[root].len = 0;
    if(left + 1 == right){
        return;
    }
    int mid = left + ((right - left) >> 1);
    build(left, mid, (root << 1) + 1, layer+1);
    build(mid, right, (root << 1) + 2, layer+1);
}

void push_up(int index,int left,int right,int layer){
    if(tree[index].cover != 0){
        tree[index].len = segment_point[right] - segment_point[left];
    }
    else if(left + 1 == right){
        tree[index].len = 0;
    }else{
        tree[index].len = tree[(index << 1) + 1].len + tree[(index << 1) + 2].len;
    }
}

void update(int root, int rl, int rr, int left,int right, int cover,int layer){
    if(left <= rl && right >= rr){
        tree[root].cover += cover;
        push_up(root, rl, rr,layer);
        return;
    }
    if(rl + 1 == rr){
        return;
    }
    int mid = rl + ((rr - rl) >> 1);
    if(left <= mid){
        update((root << 1) + 1, rl , mid, left, right, cover, layer+ 1);
    }
    if(right > mid){
        update((root << 1) + 2, mid, rr, left, right,cover,layer+1);
    }
    push_up(root, rl, rr,layer);
}
int bsearch(double* array, double value, int l, int r){
    int ll = l, rr = r;
    if(ll == rr){
        return ll;
    }
    while(ll <= rr){
        int mid = ll + ((rr - ll) >> 1);
        if(fabs(array[mid] - value) < eps){
            return mid;
        }
        if(array[mid] < value){
            ll = mid + 1;
        }
        else{
            rr = mid - 1;
        }
    }
    return ll;
}
int main() {
  //  freopen("1.txt","r",stdin);
    int n;
    int t = 1;
    double leftx, lefty, rightx, righty;
    while(scanf("%d", &n ) != EOF && n) {
        memset(tree, 0, sizeof(tree));
        scanline_vector.clear();
        memset(segment_point, 0, sizeof(segment_point));
        scanline_vector.resize(n << 1);
        int cur = 0;
        for(int i = 0; i < n; ++i){
            scanf("%lf%lf%lf%lf",&leftx, &lefty, &rightx, &righty);
            scanline_vector[(i << 1)].x = leftx;
            scanline_vector[(i << 1)].y1 = lefty;
            scanline_vector[(i << 1)].y2 = righty;
            scanline_vector[(i << 1)].cover = 1;

            scanline_vector[(i << 1) | 1].x = rightx;
            scanline_vector[(i << 1) | 1].y1 = lefty;
            scanline_vector[(i << 1) | 1].y2 = righty;
            scanline_vector[(i << 1) | 1].cover = -1;

            segment_point[cur++] = lefty;
            segment_point[cur++] = righty;
        }

        //sort and unique segment_point
        sort(segment_point, segment_point + cur);
        int read_index = 1, write_index = 1;
        while(read_index < cur){
            if(segment_point[read_index - 1] != segment_point[read_index]){
                segment_point[write_index++] = segment_point[read_index];
            }
            read_index++;
        }
        //segment_point valid length is write_index

        //build segment_tree using discreeted segment_points
        build(0, write_index - 1, 0, 1);
        sort(scanline_vector.begin(), scanline_vector.end());
        int size = scanline_vector.size();

        double sum = 0;
        for(int i = 0; i + 1 < size; i++){
            int y1index = bsearch(segment_point, scanline_vector[i].y1, 0, write_index - 1);
            int y2index = bsearch(segment_point, scanline_vector[i].y2, 0, write_index - 1);
            update(0, 0, write_index - 1, y1index, y2index, scanline_vector[i].cover,1);
            sum += (scanline_vector[i + 1].x - scanline_vector[i].x) * tree[0].len;
        }
        printf("Test case #%d\n", t++);
        printf("Total explored area: %.2lf\n",sum);
        printf("\n");
    }
    return 0;
}

coding时的错误:
1. 左右子结点的下标;
root下标为0时,右子结点是 (index << 1) + 2, 而不是(index<<1) | 2
2. 记得把freopen注释掉

相关文章推荐

zoj 1128 || poj 1151 Atlantis(线段树求矩形面积并)

纠结了好久了,终于差不多弄懂了,无语啊。以后会更难的,线段树水题都刷差不多了都。求矩形面积并啊。= =。。。先把Y坐标离散化,然后用扫描线扫描。进入的结构体标记为1,出去的为-1。所以,当一个节点进入...

poj 1151(线段树求面积并)

解题思路:线段树求面积并,水题 #include #include #include #include #include #include using namespace std; con...

POJ1151(线段树+扫描线求矩形面积并)

题目:http://poj.org/problem?id=1151   #include #include #include #include using namespace std; co...

poj 1151 线段树扫描线求图形面积

Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16975   Acce...

线段树求矩形面积并 方法详解 (扫描线)HDU 1542 & HDU 3265 & POJ 1151

线段树求矩形面积并 方法详解 (扫描线)HDU 1542 & HDU 3265 & POJ 1151

poj 1151 Atlantis “线段树维护关键值”+“离散化”+“扫描线法”

Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17448   Acce...

POJ1151 亚特兰蒂斯

Atlantis Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %I64d & %I64u ...

poj 1151(线段树+扫描+几何计算)

#include #include #include using namespace std; struct node { int st,ed,c; double m; }ST...

poj 1151 Atlantis(线段树 扫描线)

Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8759   Accep...
  • fp_hzq
  • fp_hzq
  • 2011年04月11日 18:22
  • 744

[POJ1151] Atlantis - 矩形切割

题目描述给出n个矩形,求这些矩形面积的并。输入格式输入包含多组测试数据; 每组数据的第一行包含一个整数n(1...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 1151
举报原因:
原因补充:

(最多只允许输入30个字)