Topic Link: Click to open the link
Picture
Time Limit: 2000MS |
|
Memory Limit: 10000K |
Total Submissions: 11706 |
|
Accepted: 6175 |
Description
A number of rectangular posters, photographs and other pictures of the same shape is pasted on a wall. Their sides is all vertical or horizontal. Each rectangle can is partially or totally covered by the others. The length of the boundary of the Union of all rectangles is called the perimeter.
Write a program to calculate the perimeter. An example with 7 rectangles are shown in Figure 1.
The corresponding boundary is the whole set of line segments drawn in Figure 2.
The vertices of all rectangles has an integer coordinates.
Input
Your program was to read from standard input. The first line contains the number of rectangles pasted on the wall. In the subsequent lines, one can find the integer coordinates of the lower left vertex and the upper right vertex of each rectangle. The values of those coordinates is given as ordered pairs consisting of an x-coordinate followed by a y-coordinate.
0 <= number of rectangles < 5000
All coordinates is in the range [ -10000,10000] and any existing rectangle have a positive area.
Output
Your program is-to-write to standard output. The output must contain a single line with a non-negative integer which corresponds to the perimeter for the input Rectang Les.
Sample Input
7-15 0 5 10-5 8 20 2515-4 24 140-6 16 42 15 10 2230 10 36 2034 0 40 16
Sample Output
228
Test instructions: There are many rectangles on the plane, and the rectangles will cover each other, asking the total perimeter.
Idea: See this problem to think of the rectangular area before done and, this problem than the problem to deal with a cross-side, except that it is the same ~ saw click to open the link to the idea of the great God after the enlightened.
In the previous rectangular area and the template changed the AC, the code of the specific comments, see the Code bar.
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using namespace STD; #define N 10010struct node{int l,r; int RL,RR; int c;///The weight of the segment, The edge is 1, the Out Edge is-1 int cnt;///the vertical effective length int part;///in the vertical direction valid segment has several intervals, the successive two intervals calculates one. int isl,isr;///whether the left and right endpoints of the interval are overwritten}tree[n<<2];struct line{int x; int y1,y2; int C;} Line[n<<1];int Y[n];bool cmp (line A,line b) {if (a.x==b.x) return a.c>b.c;///note whether POJ or HDU this step does not add to the AC, but The code is wrong, because the heavy edges cannot be judged. If there is a heavy edge, the first judgment of the edge can be resolved. return a.x<b.x;} void build (int root,int l,int r) {tree[root].l=l; Tree[root].r=r; TREE[ROOT].RL=Y[L]; TREE[ROOT].RR=Y[R]; tree[root].c=0; tree[root].cnt=0; tree[root].part=0; tree[root].isl=tree[root].isr=0; if (l+1==r) return; int m= (L+R) >>1; Build (ROOT<<1,L,M); Build (Root<<1|1,m,r);} void pushup (int root) {if (tree[root].c>0) {tree[root].cnt=tree[root].rr-tree[root].rl; TreE[root].isl=tree[root].isr=1; Tree[root].part=1; } else {if (TREE[ROOT].L+1==TREE[ROOT].R) {tree[root].cnt=0; tree[root].isl=tree[root].isr=0; tree[root].part=0; } else {tree[root].cnt=tree[root<<1].cnt+tree[root<<1|1].cnt; tree[root].isl=tree[root<<1].isl; tree[root].isr=tree[root<<1|1].isr; Tree[root].part=tree[root<<1].part+tree[root<<1|1].part-tree[root<<1].isr*tree[root<<1 |1].ISL; }}}void Update (int root,line a) {if (tree[root].rl==a.y1&&tree[root].rr==a.y2) {TREE[ROOT].C+=A.C ; Pushup (root); Return } if (A.Y2<=TREE[ROOT<<1].RR) {update (ROOT<<1,A); } else if (A.Y1>=TREE[ROOT<<1|1].RL) {update (ROOT<<1|1,A); } else {line temp=a; temp.y2=tree[root<<1].rr; UpdateROOT<<1,TEMP); Temp=a; temp.y1=tree[root<<1|1].rl; Update (ROOT<<1|1,TEMP); } pushup (root);} int main () {int x1,y1,x2,y2; int n; int flag=0; while (~SCANF ("%d", &n)} {if (flag==1) break; int t=1; for (int i=0;i<n;i++) {scanf ("%d%d%d%d", &x1,&y1,&x2,&y2); line[t].x=x1; Line[t].y1=y1; Line[t].y2=y2; Line[t].c=1; Y[t++]=y1; line[t].x=x2; Line[t].y1=y1; Line[t].y2=y2; Line[t].c=-1; Y[t++]=y2; }///save each edge and each Y value of sort (line+1,line+t,cmp); Sort (y+1,y+t); int num=2; for (int i=2;i<t;i++) if (y[i]!=y[i-1]) y[num++]=y[i];///de-build (1,1,NUM-1); Update (1,line[1]); int sum=tree[1].cnt; int Last_part=tree[1].part; int last_cnt=tree[1].cnt;///preprocessing the first edge, because it needs to be updated before processing for (iNT i=2;i<t;i++) {update (1,line[i]); Sum+=abs (TREE[1].CNT-LAST_CNT)////////////////When a new line segment is entered, the length of the "not internal edge" is calculated by subtracting the effective length of the update from the effective length before the update, and the area and the rectangular area are the opposite, and need exactly the length of the inner edge s um+=2*last_part* (line[i].x-line[i-1].x), or///To find a cross, a section (interval) has two sides. Note It should be easy to understand that you want to use the part value before updating. The number of bars on the side is seen from the left side, that is, we can ensure that only the previous x to the current x before the distance has the number of paragraphs before the update side length Last_part=tree[1].part; last_cnt=tree[1].cnt;///scrolling} printf ("%d\n", sum); } return 0;}
poj-1177 Picture (Rectangle perimeter and Segment tree + scan line)