POJ1151+线段树+扫描线

  1 /*
  2 线段树+扫描线+离散化
  3 求多个矩形的面积
  4 */
  5 #include<stdio.h>
  6 #include<string.h>
  7 #include<stdlib.h>
  8 #include<algorithm>
  9 #include<iostream>
 10 #include<queue>
 11 #include<stack>
 12 #include<math.h>
 13 #include<map>
 14 using namespace std;
 15 const int maxn = 105;
 16 const int maxm = 210;
 17 struct SegTree{
 18     int l,r;
 19     int cover;
 20     double L_val,R_val;
 21     double sum;
 22 }ST[ maxm<<2 ];
 23 struct Line{
 24     double x,y1,y2;
 25     bool InOut;
 26 }yLine[ maxm ];
 27 int cmp( Line a,Line b ){
 28     return a.x<b.x;
 29 }
 30 double yIndex[ maxm ];
 31 int GetIndex( double val,int cnt ){
 32     return lower_bound( yIndex,yIndex+cnt,val )-yIndex;
 33 }
 34 
 35 void build( int L,int R,int n ){
 36     ST[ n ].l = L;
 37     ST[ n ].r = R;
 38     ST[ n ].cover = 0;
 39     ST[ n ].sum = 0;
 40     ST[ n ].L_val = yIndex[ L ];
 41     ST[ n ].R_val = yIndex[ R ];
 42     if( R-L>1 ){
 43         int mid = (L+R)/2;
 44         build( L,mid,2*n );
 45         build( mid,R,2*n+1 );
 46     }
 47 }
 48 void PushUp( int n ){
 49     if( ST[ n ].cover>0 ){
 50         ST[ n ].sum = ST[ n ].R_val-ST[ n ].L_val;
 51     }
 52     else if( ST[ n ].r-ST[ n ].l>1 ){
 53         ST[ n ].sum = ST[ 2*n ].sum+ST[ 2*n+1 ].sum;
 54     }
 55     else
 56         ST[ n ].sum = 0;
 57 }
 58 void update( int left,int right,bool InOut,int n  ){
 59     if( left==ST[ n ].l&&right==ST[ n ].r ){
 60         if( InOut==true ){
 61             ST[ n ].cover++;
 62         }
 63         else{
 64             ST[ n ].cover--;
 65         }
 66     }
 67     else {
 68         int mid = (ST[ n ].l+ST[ n ].r)/2;
 69         if( mid>=right ) update( left,right,InOut,2*n );
 70         else if( mid<=left ) update( left,right,InOut,2*n+1 );
 71         else {
 72             update( left,mid,InOut,2*n );
 73             update( mid,right,InOut,2*n+1 );
 74         }
 75     }
 76     PushUp( n );
 77 }
 78 
 79 int main(){
 80     int n;
 81     int T = 1;
 82     while( scanf("%d",&n)==1,n ){
 83         printf("Test case #%d\n",T++);
 84         double x1,y1,x2,y2;
 85         int cnt = 0;
 86         for( int i=0;i<n;i++ ){
 87             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 88             yLine[ 2*i ].x = x1;
 89             yLine[ 2*i+1 ].x = x2;
 90             yLine[ 2*i ].y1 = yLine[ 2*i+1 ].y1 = y1;
 91             yLine[ 2*i ].y2 = yLine[ 2*i+1 ].y2 = y2;
 92             yLine[ 2*i ].InOut = true;
 93             yLine[ 2*i+1 ].InOut = false;
 94             yIndex[ 2*i ] = y1;
 95             yIndex[ 2*i+1 ] = y2;
 96         }
 97         sort( yLine,yLine+2*n,cmp );
 98         sort( yIndex,yIndex+2*n );
 99         for( int i=1;i<2*n;i++ ){
100             if( yIndex[i]!=yIndex[i-1] )
101                 yIndex[ cnt++ ] = yIndex[ i-1 ];
102         }
103         yIndex[ cnt++ ] = yIndex[ 2*n-1 ];
104         build( 0,cnt-1,1 );
105         double res = 0;
106         update( GetIndex( yLine[0].y1,cnt ),GetIndex( yLine[0].y2,cnt ),yLine[0].InOut,1 );
107         for( int i=1;i<2*n;i++ ){
108             res += ST[ 1 ].sum*( yLine[i].x-yLine[i-1].x );
109             update( GetIndex( yLine[i].y1,cnt ),GetIndex( yLine[i].y2,cnt ),yLine[i].InOut,1 );
110         }
111         printf("Total explored area: %.2lf\n\n",res);
112     }
113     return 0;
114 }
View Code

 

posted @ 2013-08-22 15:45  xxx0624  阅读(290)  评论(0编辑  收藏  举报