zoukankan      html  css  js  c++  java
  • hdu 1542 & poj 1151 Atlantis 线段树扫描线求矩形面积并

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542

    题意:给出n个矩形,求矩形面积并。

    思路:经典的用扫描线法求矩形面积并。由于坐标很大,可以选择离散化横坐标或者离散化纵坐标。

    如果离散化横坐标,记录每个矩形的上下两条线段的左起点,右起点和高度以及为上边或者下边。

    选择从下往上扫描,那么把矩形的下边记录为1,把矩形的上边记录为-1。

    把这些线段按高度h从小到大排序,然后从下开始往上扫描,每次遇到一条直线,如果是下边,在线段树相应区间+1。

    如果是上边,在线段树相应区间-1。然后更新总区间被覆盖的长度,每次加上该长度*(当前扫描到的直线与下一条直线的高度差)。

    画个图就比较清楚了。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 int n;
      4 #define maxn 210
      5 #define lson l, m, rt<<1
      6 #define rson m+1, r, rt<<1|1
      7 struct Line
      8 {
      9     double l, r, h;
     10     int mark;
     11 }line[maxn];
     12 double a[maxn], b[maxn];
     13 map <int, double> mp;
     14 int cnt;
     15 bool cmp(Line l1, Line l2)
     16 {
     17     return l1.h < l2.h;
     18 }
     19 int sum[maxn<<2];
     20 double cover[maxn<<2];
     21 void pushup(int l, int r, int rt)
     22 {
     23     if(sum[rt]) cover[rt] = mp[r+1] - mp[l];
     24     else
     25     {
     26         if(r == l) cover[rt] = 0;
     27         else cover[rt] = cover[rt<<1] + cover[rt<<1|1];
     28     }
     29 }
     30 void build(int l, int r, int rt)
     31 {
     32     cover[rt] = 0; sum[rt] = 0;
     33     if(l == r) return;
     34     int m = (l+r)>>1;
     35     build(lson);
     36     build(rson);
     37     pushup(l, r, rt);
     38 }
     39 void update(int L, int R, int val, int l, int r, int rt)
     40 {
     41     if(L == l && R == r)
     42     {
     43         sum[rt] += val;
     44         pushup(l, r, rt);
     45         return;
     46     }
     47     int m = (l+r)>>1;
     48     if(R <= m) update(L, R, val, lson);
     49     else if(L > m) update(L, R, val, rson);
     50     else
     51     {
     52         update(L, m, val, lson);
     53         update(m+1, R, val, rson);
     54     }
     55     pushup(l, r, rt);
     56 }
     57 int main() 
     58 {
     59     //freopen("in.txt", "r", stdin);
     60     //freopen("out.txt", "w", stdout);
     61     int cast = 0;
     62     while(~scanf("%d", &n) && n)
     63     {
     64         cnt = 0; mp.clear();
     65         for(int i = 1; i <= n; i++)
     66         {
     67             double x1, y1, x2, y2;
     68             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
     69             a[cnt++] = x1; a[cnt++] = x2;
     70             
     71             line[i*2-1].l = x1; line[i*2-1].r = x2;    //下边
     72             line[i*2-1].h = y1; line[i*2-1].mark = 1; 
     73             
     74             line[i*2].l = x1; line[i*2].r = x2;
     75             line[i*2].h = y2; line[i*2].mark = -1;     //上边
     76         }
     77         for(int i = 0; i < cnt; i++) b[i] = a[i];
     78         sort(a, a+cnt);
     79         int precnt = cnt;
     80         cnt = unique(a, a+cnt) - a;
     81         
     82         for(int i = 0; i < precnt; i++)
     83         {
     84             mp[lower_bound(a, a+cnt, b[i]) - a + 1] = b[i];
     85         }
     86         sort(line+1, line+1+2*n, cmp);
     87         
     88         build(1, cnt, 1);
     89         double ans = 0;
     90         for(int i = 1; i <= 2*n; i++)
     91         {
     92             int ll = lower_bound(a, a+cnt, line[i].l) - a + 1;
     93             int rr = lower_bound(a, a+cnt, line[i].r) - a + 1;
     94             update(ll, rr-1, line[i].mark, 1, cnt, 1); 
     95             if(i != 2*n) ans += cover[1]*(line[i+1].h - line[i].h); 
     96         }
     97         cast++; printf("Test case #%d
    ", cast);
     98         printf("Total explored area: %.2f
    
    ", ans);
     99         
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    PAT顶级 1024 Currency Exchange Centers (35分)(最小生成树)
    Codeforces 1282B2 K for the Price of One (Hard Version)
    1023 Have Fun with Numbers (20)
    1005 Spell It Right (20)
    1092 To Buy or Not to Buy (20)
    1118 Birds in Forest (25)
    1130 Infix Expression (25)
    1085 Perfect Sequence (25)
    1109 Group Photo (25)
    1073 Scientific Notation (20)
  • 原文地址:https://www.cnblogs.com/titicia/p/5528544.html
Copyright © 2011-2022 走看看