The input file is terminated by a line containing a single 0. Don't process it.
Output a blank line after each test case.
As the name suggests, the scanning method is rectangular with a sweep of all imaginary line in the process of writing code, this line is very important. Direction, it can sweep around, may sweep down. The method is the same, here I use bottom-up scanning.
Shown, there are two rectangles within a coordinate system as in FIG. It is given by the position coordinates of the top right and bottom left vertex. Vertical scanning is based on the x-axis segment tree, y rectangle two parallel sides is of no use, directly remove here. As shown below.
Now imagine a line sequential scanning start up from the bottom side. Segment tree is used to maintain current coverage in the x-axis segment of the total length, total length is initially zero. Ret to save the total area of a rectangle, initially zero.
Up by the scan, to scan a rectangular base segment tree is inserted into it, when the bottom edge of the scan line is deleted from the tree to the top of the rectangle. The method is implemented in the code, each edge has a flag variable, a bottom edge, top edge -1.
Cover with an array (maintained by the segment tree) to indicate whether there is an edge within the coverage range x coordinate, initially all zero. Insert or delete operation directly cover [] + = flag. When the cover []> 0, the edge section must be covered.
To start scanning the first line, it will be pressed into the segment tree, in this case covering the overall length L of the line segment 10 is the x-axis. Calculate it to be scanned at a distance from the edge of S (i.e., the difference between the ordinate of the line segments, in this case 3 in this example).
The ret + = L * S. (example in increments of 10 * 3 = 30)
The results shown below
Orange area indicates the area that has been calculated.
Scan to the second edge, pressed into the segment tree is calculated at this time covered on the x axis side of the total length.
Examples in this case L = 15. And a lower side to be scanned distance S = 2. ret + = 30. As shown below.
Green area for the second time increment area.
Then scan the top side of the lower rectangle, the rectangle is deleted from the bottom edge of the segment tree, and calculates the next increment area. As shown below.
Blue area increments area.
At this time, the total area of the rectangular footprint has been calculated completed. Can be seen that, when a total of n base and a top edge, only scan from the bottom up to the n-1 side calculates the total area.
(Reference to God blog)
***************************************************************************************************************************
. 1 #include <cstdio> 2 #include <CString> . 3 #include <algorithm> . 4 the using namespace STD; . 5 #define INF 0x3f3f3f3 . 6 #define MAX 110 . 7 #define L (RT) RT <<. 1 . 8 #define R & lt (RT ) RT << 1 | 1 . 9 10 struct segment // save the rectangular upper and lower boundaries . 11 { 12 is Double L, R & lt, H; // left abscissa, ordinate 13 is int F; // -1 for the lower bound, the upper 1 boundary 14 } SS [ 2 *MAX]; 15 struct Node // segment tree node 16 { . 17 int L, R & lt; 18 is int CNT; // where the node is covered . 19 Double len; // total length of the covered section 20 is int MID () 21 is { return (L + R & lt) >> . 1 ;} 22 is } Tree [ 2 * * MAX . 4 ]; 23 is Double POS [MAX << 2 ]; 24 int the nums; 25 26 is int CMP (segment A, segment B) 27 { 28 return a.h<b.h; 29 } 30 31 void build(int a, int b ,int rt) 32 { 33 tree[rt].l=a; tree[rt].r=b; tree[rt].cnt=0; tree[rt].len=0; 34 if(a==b) return ; 35 int mid=tree[rt].mid(); 36 build(a,mid,L(rt)); 37 build(mid+1,b,R(rt)); 38 } 39 40 int binary(double key ,int low, int high) 41 { 42 while(low<=high) 43 { 44 int mid=(low+high)>>1; 45 if(pos[mid] == key) return mid; 46 else if(key < pos[mid]) high=mid-1; 47 else low=mid+1; 48 } 49 return -1; 50 } 51 52 void get_len ( int RT) 53 is { 54 is IF (Tree [RT] .cnt) // non-zero, has been covered the whole 55 Tree [RT] = .LEN POS [Tree [RT] .r + . 1 ] - POS [Tree [RT] .L]; 56 is the else IF (Tree [RT] .L == Tree [RT] .r) // not the line segment 57 is Tree [RT] .LEN = 0 ; 58 the else // is but one segment and no cover the whole, it can be obtained from information about the child's 59 Tree [RT] Tree .LEN = [L (RT)] + len. Tree [R & lt (RT)] len;. 60 } 61 is 62 is void UPDATA ( int A,int B, int Val, int RT) 63 is { 64 IF (Tree [RT] .L && == A Tree [RT] .r == B) // target section 65 { 66 Tree [RT] + = Val .cnt ; // update interval is covered in this case 67 get_len (RT); // updates the total length of this interval is covered by the 68 return ; 69 } 70 int MID = Tree [RT] .mid (); 71 is IF (B <= MID) // only access the left child 72 UPDATA (A, B, Val, L (RT)); 73 is the else IF (A> MID) //Children have access only 74 UPDATA (A, B, Val, R & lt (RT)); 75 the else // about to be accessed 76 { 77 UPDATA (A, MID, Val, L (RT)); 78 UPDATA (MID + . 1 , B, Val, R & lt (RT)); 79 } 80 get_len (RT); // calculate the total length of the covered section 81 } 82 83 int main () 84 { 85 int Case = 0 ; 86 int n-; 87 the while (Scanf ( " % D " , & n-)! && the EOF = n-) 88 { 89 nums=0; 90 for(int i=0; i<n; i++) 91 { 92 double x1,y1,x2,y2; 93 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 94 ss[nums].l=x1; ss[nums].r=x2; ss[nums].h=y1; ss[nums].f=1; 95 //记录上边界的信息 96 ss[nums+1].l=x1; ss[nums+1].r=x2; ss[nums+1].h=y2; ss[nums+1].f=-1 ; 97 // record boundary information 98 POS [the nums] = X1; POS [the nums + 1 ] = X2; 99 // record the abscissa 100 the nums = + 2 ; 101 102 } 103 104 Sort (SS, SS + the nums , CMP); // horizontal sorted in ascending ordinate 105 Sort (POS, POS + the nums); // abscissa ascending order of 106 // for (int I = 0; I <the nums; I ++) the printf ( "%. %% .2lf .2lf 2Lf \ n-", SS [I] .L, SS [I] .r, SS [I] .h); 107 int m = . 1 ; 108 for ( int I = . 1; I <the nums; I ++ ) 109 IF ! (POS [I] POS = [I- . 1 ]) // deduplication 110 POS [++ m] = POS [I]; 111 112 Build ( 0 , M- . 1 , . 1 ) ; // interval is discretized [0, m-1], this contribution 113 Double ANS = 0 ; 114 for ( int I = 0 ; I <the nums; I ++) // out of each horizontal line and updating 115 { 1 16 int L = binary (SS [I] .L, 0 , M- . 1 ); 117 int r=binary(ss[i].r,0,m-1)-1; 118 updata(l,r,ss[i].f,1); //用这条线段去更新 119 ans += (ss[i+1].h-ss[i].h)*tree[1].len; 120 //printf("%.2lf\n",ans); 121 } 122 printf("Test case #%d\n",++Case); 123 printf("Total explored area: %.2f\n\n",ans); 124 } 125 return 0; 126 }
Reproduced in: https: //www.cnblogs.com/sdau--codeants/p/3531305.html