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注释掉

POJ1151Atlantis【离散化+扫描线+线段树】

Language: Default Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submi...
  • R1986799047
  • R1986799047
  • 2015年09月15日 22:09
  • 501

poj 1151 Atlantis 纯矩形面积并

以端点建树,所以对于l,r 它的
  • cqsh3vj2
  • cqsh3vj2
  • 2014年07月16日 11:19
  • 275

POJ 1151 Atlantis 线段树扫描线

题目:http://poj.org/problem?id=1151 题意:给出n个矩形,给出的方式为给出矩形的左下角和右上角两个点,问这些矩形覆盖的面积 思路:线段树扫描线第一题,留个模板 #incl...
  • discreeter
  • discreeter
  • 2016年08月10日 17:52
  • 203

poj 1151 hdu 1542 Atlantis 线段树扫描线,详细讲解,(*^__^*) 嘻嘻……

我的扫面线第一题,一开始看网上讲的都好抽象,最后还是研究别人代码整明白的,所以我要写一个直观的,哈哈哈!!希望大家都能看懂 如图虚线将整个图型分成三个矩形,我们现将每个点的x进行排序,也就是(10,1...
  • youngyangyang04
  • youngyangyang04
  • 2012年07月26日 10:32
  • 9231

POJ1151 Atlantis 【扫描线】

Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16882   Accepted: 6435 ...
  • u012846486
  • u012846486
  • 2014年07月15日 23:09
  • 1299

POJ 1151 Atlantis(重叠矩阵面积和=离散化)

POJ 1151 Atlantis(重叠矩阵面积和=离散化) http://poj.org/problem?id=1151 题意:        给你n个边平行于坐标轴的矩阵(任意两个矩阵可能重...
  • u013480600
  • u013480600
  • 2014年09月16日 20:27
  • 1934

poj1151-- Atlantis(线段树+离散化+扫描线)

Atlantis Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Sta...
  • u013015642
  • u013015642
  • 2014年08月11日 17:03
  • 1353

lightoj 1151 概率dp + 高斯消元

链接:vjudge.. 题意:10*10的地图,不过可以直接看成1*100的,从1出发,要到达100,每次走的步数用一个完美的大小为6的骰子决定。地图上有A和B,A和B都使你跳跃,不过一个是往前跳,...
  • u013307987
  • u013307987
  • 2015年07月04日 14:40
  • 761

杭电ACM1151

今天的第二道匈牙利算法题目。 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1151 题目大意:在一个镇子里由街道连接了许多交叉路口,并且这些街道都...
  • Runner__1
  • Runner__1
  • 2015年11月05日 21:46
  • 268

poj 1151

原题:The Last Non-zero DigitTime Limit: 1000MS Memory Limit: 65536KTotal Submissions: 3104 Accepted: 8...
  • New_C_YUER
  • New_C_YUER
  • 2010年11月17日 00:47
  • 863
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 1151
举报原因:
原因补充:

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