poj1151 Atlanis 线段树+离散化求矩形面积的并

题目链接:http://poj.org/problem?id=1151

很经典的题目,网上有很多模板代码,自己理解了一天,然后很容易就敲出来了。。。

代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<algorithm>
  6 #define maxn 110
  7 using namespace std;
  8 int n;
  9 class node
 10 {
 11    public:
 12    int l,r;//端点坐标的映射值(整数值)
 13    double cnt;
 14    double c;
 15    double lf,rf;//实际的端点坐标
 16 };
 17 node segTree[maxn*3];
 18 class Line
 19 {
 20    public:
 21    double x;
 22    double y1;
 23    double y2;
 24    double f;//f=1表示左边,f=-1表示矩形的右边
 25 };
 26 Line line[maxn];
 27 double y[maxn];
 28 bool cmp(Line a, Line b)
 29 {
 30     return a.x < b.x;
 31 }
 32 void Build(int num, int l, int r)
 33 {
 34    segTree[num].l=l;
 35    segTree[num].r=r;
 36    segTree[num].cnt=segTree[num].c=0;
 37    segTree[num].lf=y[l];
 38    segTree[num].rf=y[r];
 39    if(l+1==r) return ;
 40    int mid=(l+r)/2;
 41    Build(num*2,l,mid);
 42    Build(num*2+1,mid,r);
 43 }
 44 void calen(int num)//计算边的有效长度
 45 {
 46     if(segTree[num].c > 0) //表示当前边为直接有效部分 cnt存边的长度
 47      {
 48         segTree[num].cnt=segTree[num].rf-segTree[num].lf;
 49         return ;
 50      }
 51    else//如果当前边不是直接有效部分 可以理解为当前边已经不存在
 52      {
 53         if(segTree[num].l+1 ==segTree[num].r) //如果当前边为最小的单元(就是没有孩子了),那么其间接有效长度为0
 54         {
 55             segTree[num].cnt=0;
 56         }
 57         else//否则其有效长度为孩子的有效长度和
 58          {
 59                segTree[num].cnt=segTree[num*2].cnt+segTree[num*2+1].cnt;
 60                return ;
 61          }
 62 
 63      }
 64 }
 65 void Update(int num,Line e)
 66 {
 67     if(segTree[num].lf== e.y1 && segTree[num].rf ==e.y2)
 68     {
 69         segTree[num].c+=e.f;
 70         calen(num);
 71         return ;
 72     }
 73     if(segTree[num*2].rf>=e.y2) Update(num*2,e);
 74     else
 75        if(segTree[num*2+1].lf<=e.y1) Update(num*2+1,e);
 76         else
 77         {
 78             Line tmp=e;
 79             tmp.y2=segTree[num*2].rf;
 80             Update(num*2,tmp);
 81             tmp=e;
 82             tmp.y1=segTree[num*2+1].lf;
 83             Update(num*2+1,tmp);
 84         }
 85         calen(num);
 86 }
 87 int main()
 88 {
 89       int iCase=1;
 90       double x1,x2,y1,y2;
 91      while(scanf("%d",&n)!=EOF  && n)
 92      {
 93          int t=1;
 94          for(int i=1;i<=n;i++)
 95          {
 96              scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 97              line[t].x=x1;
 98              line[t].y1=y1;
 99              line[t].y2=y2;
100              line[t].f=1;
101              y[t]=y1;
102              t++;
103              line[t].x=x2;
104              line[t].y1=y1;
105              line[t].y2=y2;
106              line[t].f=-1;
107              y[t]=y2;
108              t++;
109           }
110          sort(y+1,y+t);
111          sort(line+1,line+t,cmp);
112          Build(1,1,t-1);
113          Update(1,line[1]);
114          double ans=0;
115          for(int i=2;i<t;i++)
116             {
117                   ans+=segTree[1].cnt*(line[i].x- line[i-1].x);
118                   Update(1,line[i]);
119                   //segTree[1].cnt是位于坐标line[i-1].x的最终的有效边长
120             }
121        printf("Test case #%d\nTotal explored area: %.2f\n\n",iCase++,ans);  
122 
123      }
124     
125    return 0;
126 }

 

posted on 2013-10-07 16:34  GyyZyp  阅读(165)  评论(0编辑  收藏  举报

导航