设为首页 加入收藏

TOP

hdu1255 线段树+扫描线+离散化
2015-07-20 17:33:08 来源: 作者: 【 】 浏览:2
Tags:hdu1255 线段 扫描 离散

题意是求矩形覆盖2次以上的面积

第一道扫面线题 看了网上一些扫描线的讲解 没怎么看懂 自己试着敲了一下 感觉还行 比较容易懂

关于扫描线的概念就不多说了 直接上题

离散化:对x轴

线段树 :对离散后的x值

扫描线:对与x轴平行的边

注意节点的的子树 应为必须是一个区间 所有最小区间为为1-2 2-3 3-4 4-5 ??????????

#include
  
   
#include
   
     #include
    
      #include
      
      using namespace std
      ; #define LL(x) (x<<1) #define RR(x) ((x<<1)|1) 
       struct node
       { double y
      ; int x1
      ,x2
      ; int flash
      ; }A
      [3100
      ]; struct Node
       { double x
      ; int tt
      ; int ii
      ; }scatter
      [3100
      ]; int leap
      [10000
      ];//标记节点 如果==-1说明当前节点表示的区间不是不是一样的值 否则为对应的值 int n
      ; double map
      [3100
      ];//每个下标对应浮点型x的值 int cmp
      (Node a
      ,Node b
      ) { return a
      .x
      <b
      .x
      ; } int cmp2
      (Node a
      ,Node b
      ) { if(a
      .ii
      !=b
      .ii
      ) return a
      .ii
      <b
      .ii
      ; else return a
      .x
      <b
      .x
      ; } int cmp3
      (node a
      ,node b
      ) { return a
      .y
      <b
      .y
      ; } int update
      (int L
      ,int R
      ,int left
      ,int right
      ,int mark
      ,int k
      ) { int mid
      =(L
      +R
      )/2
      ; if(L
      ==left
      &&right
      ==R
      ) { if(leap
      [mark
      ]>=0
      ) { leap
      [mark
      ]+=k
      ; } else { update
      (L
      ,mid
      ,L
      ,mid
      ,LL
      (mark
      ),k
      ); update
      (mid
      ,R
      ,mid
      ,R
      ,RR
      (mark
      ),k
      ); if(leap
      [LL
      (mark
      )]==leap
      [RR
      (mark
      )]) leap
      [mark
      ]=leap
      [LL
      (mark
      )]; } } else { if(leap
      [mark
      ]>=0
      ) { leap
      [LL
      (mark
      )]=leap
      [mark
      ]; leap
      [RR
      (mark
      )]=leap
      [mark
      ]; } if(right
      <=mid
      ) { update
      (L
      ,mid
      ,left
      ,right
      ,LL
      (mark
      ),k
      ); } else if(left
      >=mid
      ) { update
      (mid
      ,R
      ,left
      ,right
      ,RR
      (mark
      ),k
      ); } else { update
      (L
      ,mid
      ,left
      ,mid
      ,LL
      (mark
      ),k
      ); update
      (mid
      ,R
      ,mid
      ,right
      ,RR
      (mark
      ),k
      ); } if(leap
      [LL
      (mark
      )]==leap
      [RR
      (mark
      )]) leap
      [mark
      ]=leap
      [LL
      (mark
      )]; else leap
      [mark
      ]=-1
      ; } return 0
      ; } double find
      (int L
      ,int R
      ,int mark
      ) { double dis
      =0
      ; if(leap
      [mark
      ]>=2
      ) { dis
      +=map
      [R
      ]-map
      [L
      ]; return dis
      ; } if(leap
      [mark
      ]>=0
      ) return 0
      ; int mid
      =(L
      +R
      )/2
      ; dis
      +=find
      (L
      ,mid
      ,LL
      (mark
      ))+find
      (mid
      ,R
      ,RR
      (mark
      )); return dis
      ; } int main() { int T
      ,i
      ,j
      ,a
      ,b
      ; double x1
      ,y1
      ,x2
      ,y2
      ; scanf
      ("%d"
      ,&T
      ); while(T
      --) { scanf
      ("%d"
      ,&n
      ); memset
      (A
      ,0
      ,sizeof(A
      )); memset
      (map
      ,0
      ,sizeof(map
      )); for(i
      =1
      ;i
      <=2
      *n
      ;i
      +=2
      ) { scanf
      ("%lf%lf%lf%lf"
      ,&x1
      ,&y1
      ,&x2
      ,&y2
      ); A
      [i
      ].y
      =y1
      ; A
      [i
      ].flash
      =1
      ; A
      [i
      +1
      ].y
      =y2
      ; A
      [i
      +1
      ].flash
      =-1
      ; scatter
      [i
      ].x
      =x1
      ; scatter
      [i
      ].ii
      =i
      ; scatter
      [i
      +1
      ].x
      =x2
      ; scatter
      [i
      +1
      ].ii
      =i
      ; } sort
      (scatter
      +1
      ,scatter
      +2
      *n
      +1
      ,cmp
      );//对x来离散 应为x值为浮点型 不能成为数组下标 double k
      =-1
      ; int j
      =0
      ; for(i
      =1
      ;i
      <=2
      *n
      ;i
      ++) { if(scatter
      [i
      ].x
      !=k
      ) { k
      =scatter
      [i
      ].x
      ; scatter
      [i
      ].tt
      =++j
      ; map
      [j
      ]=scatter
      [i
      ].x
      ; } else scatter
      [i
      ].tt
      =j
      ; } sort
      (scatter
      +1
      ,scatter
      +2
      *n
      +1
      ,cmp2
      ); for(i
      =1
      ;i
      <=2
      *n
      ;i
      +=2
      ) { A
      [i
      ].x1
      =scatter
      [i
      ].tt
      ; A
      [i
      ].x2
      =scatter
      [i
      +1
      ].tt
      ; A
      [i
      +1
      ].x1
      =scatter
      [i
      ].tt
      ; A
      [i
      +1
      ].x2
      =scatter
      [i
      +1
      ].tt
      ; } sort
      (A
      +1
      ,A
      +2
      *n
      +1
      ,cmp3
      );//把所有与x轴平行的边按对应的y值排序 memset
      (leap
      ,0
      ,sizeof(leap
      )); double area
      =0
      ; a
      =A
      [1
      ].x1
      ; b
      =A
      [1
      ].x2
      ; update
      (1
      ,j
      ,a
      ,b
      ,1
      ,1
      ); for(i
      =2
      ;i
      <=2
      *n
      ;i
      ++) { a
      =A
      [i
      ].x1
      ; b
      =A
      [i
      ].x2
      ; area
      +=(A
      [i
      ].y
      -A
      [i
      -1
      ].y
      )*find
      (1
      ,j
      ,1
      ); if(A
      [i
      ].flash
      ==1
      ) update
      (1
      ,j
      ,A
      [i
      ].x1
      ,A
      [i
      ].x2
      ,1
      ,1
      ); else update
      (1
      ,j
      ,A
      [i
      ].x1
      ,A
      [i
      ].x2
      ,1
      ,-1
      ); } printf
      ("%.2lf\n"
      ,area
      ); } return 0
      ; }
     
    
   
  



】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇POJ Hard Life (最大密度子图) 下一篇ZOJ 1204 Additive equations(深..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·JAVA现在的就业环境 (2025-12-26 01:19:24)
·最好的java反编译工 (2025-12-26 01:19:21)
·预测一下2025年Java (2025-12-26 01:19:19)
·Libevent C++ 高并发 (2025-12-26 00:49:30)
·C++ dll 设计接口时 (2025-12-26 00:49:28)