POJ1151-扫面线+线段树+离散化//入门题

比较水的入门题

记录矩形竖边的x坐标,离散化排序。以被标记的边建树。

扫描线段树,查询线段树内被标记的边。遇到矩形的右边就删除此边

每一段的面积是查询结果乘边的横坐标之差,求和就是答案

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 
  5 using namespace std;
  6 const int maxn = 1000;
  7 int N,num,kase;
  8 double savey[maxn*2];
  9 
 10 struct line{
 11     double x,y1,y2;
 12     int flag;
 13     bool operator < (const struct line &t) const {return x < t.x;}
 14 }Line[maxn];
 15 
 16 struct Node{
 17     int l,r;
 18     double dl,dr;
 19     double len;
 20     int flag;
 21 }SegTree[maxn*4];
 22 
 23 void Build(int i,int l,int r)
 24 {
 25     SegTree[i].l = l;
 26     SegTree[i].r = r;
 27     SegTree[i].flag = SegTree[i].len = 0;
 28     SegTree[i].dl = savey[l];
 29     SegTree[i].dr = savey[r];
 30     if(l +1 == r) return;
 31     int mid = (l+r)>>1;
 32     Build(i<<1,l,mid);
 33     Build(i<<1|1,mid,r);
 34 }
 35 
 36 void getlen(int t)
 37 {
 38     if(SegTree[t].flag > 0)
 39     {
 40         SegTree[t].len = SegTree[t].dr - SegTree[t].dl;
 41         return ;
 42     }
 43     if(SegTree[t].l+1 == SegTree[t].r) SegTree[t].len = 0;
 44     else SegTree[t].len = SegTree[t<<1].len + SegTree[t<<1|1].len;
 45 }
 46 
 47 void Update(int i,line e)
 48 {
 49     if(e.y1 == SegTree[i].dl && e.y2 == SegTree[i].dr)
 50     {
 51         SegTree[i].flag += e.flag;
 52         getlen(i);
 53         return;
 54     }
 55     if(e.y2 <= SegTree[i<<1].dr) Update(i<<1,e);
 56     else if(e.y1 >= SegTree[i<<1|1].dl)    Update(i<<1|1,e);
 57     else 
 58     {
 59         line temp = e;
 60         temp.y2 = SegTree[i<<1].dr;
 61         Update(i<<1,temp);
 62         temp = e;
 63         temp.y1 = SegTree[i<<1|1].dl;
 64         Update(i<<1|1,temp);
 65     }
 66     getlen(i);
 67 }
 68 
 69 int main()
 70 {
 71     while(~scanf("%d",&N) && N)
 72     {
 73         kase++;
 74         num=1;
 75         double x1,x2,y1,y2;
 76         for(int i=1;i<=N;i++)
 77         {
 78             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 79             Line[num].x = x1;
 80             Line[num].y1 = y1;
 81             Line[num].y2 = y2;
 82             Line[num].flag = 1;
 83             savey[num++]=y1;
 84             Line[num].x = x2;
 85             Line[num].y1 = y1;
 86             Line[num].y2 = y2;
 87             Line[num].flag = -1;
 88             savey[num++] = y2;
 89         }
 90         sort(Line+1,Line+num);
 91         sort(savey+1,savey+num);
 92         Build(1,1,num-1);
 93         Update(1,Line[1]);
 94         double ans = 0;
 95         for(int i=2;i<num;i++)
 96         {
 97             //printf("%f %f
",SegTree[1].len,Line[i].x-Line[i-1].x);
 98             ans += SegTree[1].len * (Line[i].x - Line[i-1].x);
 99             Update(1,Line[i]);
100         }
101         printf("Test case #%d
",kase);
102         printf("Total explored area: %.2f

",ans);
103     }    
104     return 0;
105 }
原文地址:https://www.cnblogs.com/helica/p/4718784.html