zoukankan      html  css  js  c++  java
  • 一道离散化+线段树+扫描线的题

    http://poj.org/problem?id=1151

    这道题感觉快哭了  卡了一个差不多礼拜  然后发现 输出用%.2lf是过不了的  必须用%.2f才能过 这是一道好(lan)题;

    %f 一般对应单精度类型 float
    %lf 一般对应双精度类型 double

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cmath>
      4 #include<set>
      5 #include<cstdio>
      6 
      7 using namespace std;
      8 
      9 double y[210];
     10 typedef struct _NODE_
     11 {
     12     int L,R;
     13     _NODE_ *PLeft,*PRight;
     14     double Len;   //当前,本区间上有多长的部分是落在那些矩形中的
     15     int Covers;   //本区间当前被多少个矩形完全包含
     16 }NODE;
     17 
     18 NODE Tree[10000];
     19 
     20 typedef struct _LINE_
     21 {
     22     double x,y,y1,y2;
     23     bool bLeft;      //是否是矩形的左边
     24 }LINE;
     25 
     26 LINE Line[210];
     27 
     28 int iNodeCount = 0;
     29 bool operator < (const LINE& l1,const LINE& l2)
     30 {
     31     return l1.x < l2.x;
     32 }
     33 template<class F,class T>
     34 F bin_search(F s,F e,T val)
     35 {
     36     F  L = s;
     37     F  R = e-1;
     38     while (L<=R)
     39     {
     40         F mid = L+(R-L)/2;
     41         if (!(*mid<val||val<*mid))
     42         {
     43             return mid;
     44         }
     45         else if (val<*mid)
     46         {
     47             R = mid-1;
     48         }
     49         else 
     50         {
     51             L = mid+1;
     52         }
     53     }
     54     return e;
     55 }
     56 int Mid(NODE* PRoot)
     57 {
     58     return (PRoot->L+PRoot->R)>>1;
     59 }
     60 void Insert(NODE* PRoot,int L,int R)
     61 {
     62     if (PRoot->L==L&&PRoot->R==R)
     63     {
     64         PRoot->Len = y[R+1]-y[L];
     65         PRoot->Covers++;
     66         return ;
     67     }
     68     if (R <= Mid(PRoot))
     69     {
     70         Insert(PRoot->PLeft,L,R);
     71     }
     72     else if (L>=Mid(PRoot)+1)
     73     {
     74         Insert(PRoot->PRight,L,R);
     75     }
     76     else 
     77     {
     78         Insert(PRoot->PLeft,L,Mid(PRoot));
     79         Insert(PRoot->PRight,Mid(PRoot)+1,R);
     80     }
     81     if (PRoot->Covers==0) //如果不为0,则说明本区间当前仍然被某个矩形完全包含,则不能更新 Len
     82     {
     83         PRoot->Len = PRoot->PLeft->Len + PRoot->PRight->Len;
     84     }
     85 }
     86 
     87 
     88 void Delete(NODE* PRoot,int L,int R) //在区间pRoot 删除矩形右边的一部分或全部,该矩形右边的一部分或全部覆盖了区间[L,R]
     89 {
     90     if (PRoot->L==L&&PRoot->R==R)
     91     {
     92         PRoot->Covers--;
     93         if (PRoot->Covers==0)
     94         {
     95             if (PRoot->L==PRoot->R)
     96             {
     97                 PRoot->Len = 0;
     98             }
     99             else 
    100             {
    101                 PRoot->Len = PRoot->PLeft->Len+PRoot->PRight->Len;
    102             }
    103         }
    104         return ; 
    105     }
    106     if (R<=Mid(PRoot))
    107     {
    108         Delete(PRoot->PLeft,L,R);
    109     }
    110     else if (L>=Mid(PRoot)+1)
    111     {
    112         Delete(PRoot->PRight,L,R);
    113     }
    114     else 
    115     {
    116         Delete(PRoot,L,Mid(PRoot));
    117         Delete(PRoot->PRight,Mid(PRoot)+1,R);
    118     }
    119     if (PRoot->Covers==0) //如果不为0,则说明本区间当前仍然被某个矩形完全包含,则不能更新 Len
    120     {
    121         PRoot->Len = PRoot->PLeft->Len+PRoot->PRight->Len;
    122     }
    123 }
    124 
    125 void BuildTree(NODE* PRoot,int L,int R)
    126 {
    127     PRoot->L = L;
    128     PRoot->R = R;
    129     PRoot->Covers = 0;
    130     PRoot->Len = 0;
    131     if (L == R)
    132     return ;
    133     iNodeCount++;
    134     PRoot->PLeft = Tree + iNodeCount;
    135     iNodeCount++;
    136     PRoot->PRight = Tree+ iNodeCount;
    137     BuildTree(PRoot->PLeft,L,(L+R)/2);
    138     BuildTree(PRoot->PRight,(L+R)/2+1,R);
    139 }
    140 
    141 
    142 void work()
    143 {
    144     int i,j,k,n;
    145     double x1,x2,y1,y2;
    146     int yc,lc;
    147     int iCount = 0;
    148     int t = 0;
    149     
    150 //yc 是横线的条数,yc- 1是纵向区间的个数,这些区间从0
    151 //开始编号,那么最后一个区间
    152 //编号就是yc - 1 -1
    153     while (~scanf("%d",&n)&&n)
    154     {
    155         t++; yc = lc = 0;
    156         for (i = 0;i<n;i++)
    157         {
    158             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    159             y[yc++] = y1;  y[yc++] = y2;
    160             Line[lc].x = x1; Line[lc].y1 = y1;
    161             Line[lc].y2 = y2; Line[lc].bLeft = true;
    162             lc++;
    163             Line[lc].x = x2;  Line[lc].y1 = y1;
    164             Line[lc].y2 = y2; Line[lc].bLeft = false;
    165             lc++;
    166         }
    167         sort(y,y+yc);
    168         yc = unique(y,y+yc)-y;
    169         iNodeCount = 0;
    170         BuildTree(Tree,0,yc-1-1);
    171         sort(Line,Line+lc);
    172         double Area = 0;
    173         for (i = 0;i<lc-1;i++)
    174         {
    175             int L = bin_search(y,y+yc,Line[i].y1)-y;
    176             int R = bin_search(y,y+yc,Line[i].y2)-y;
    177             if (Line[i].bLeft)
    178             {
    179                 Insert(Tree,L,R-1);
    180             }
    181             else 
    182             {
    183                 Delete(Tree,L,R-1);
    184             }
    185             Area += Tree[0].Len*(Line[i+1].x-Line[i].x);
    186         }
    187         printf("Test case #%d
    ",t);
    188         printf("Total explored area: %.2f
    ",Area);
    189         printf("
    ");
    190     }
    191     return ;
    192 }
    193 
    194 int main()
    195 {
    196     work();
    197     return 0;
    198 }
    代码大哥
    爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
  • 相关阅读:
    ASIHTTPRequest详解
    UIViewController之间的相互跳转
    IOS延时加载网络图片
    ASI 实现注册方法的小例子(get和post方式)
    NSRange
    NSScanner
    序列化 NSKeyedArchiver,NSPropertyListSerialization
    自定义UITableViewCell
    UITableView去掉分隔符
    ASIHTTPRequest类库简介和使用说明(转)
  • 原文地址:https://www.cnblogs.com/yifi/p/4572495.html
Copyright © 2011-2022 走看看