很经典的题,我是学习的罗老的代码。就是给出一些矩形,求所有矩形重叠后最终图形的边长。思路就是(内部资料,不得外传)。这题的一个坑就是矩形的边重合时的情况。
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define N 5005 5 #define M 20005 6 int ans; 7 struct Seg 8 { 9 int x,y1,y2; 10 bool f; 11 Seg(){} 12 Seg(int a,int b,int c,bool d) 13 { 14 x = a; y1 = b; 15 y2 = c; f = d; 16 } 17 bool operator<(const Seg &s)const 18 { 19 if(x == s.x) return f > s.f; 20 else return x < s.x; 21 } 22 }; 23 Seg segx[N<<1],segy[N<<1]; 24 int tree[M<<2]; 25 void inst(int u,int x,int y,int s,int t,int val) 26 { 27 int mid=(x+y)>>1,lc=u<<1,rc=lc|1; 28 if(s <= x && y <= t && tree[u] != -1) 29 { 30 tree[u] += val; 31 if((val == 1 && tree[u] == 1)) 32 // (val == -1 && tree[u] == 0) || 33 ans += y-x+1; 34 return ; 35 } 36 if(tree[u] != -1) 37 tree[lc] = tree[rc] = tree[u]; 38 tree[u] = -1; 39 if(s <= mid) inst(lc,x,mid,s,t,val); 40 if(t >= mid+1) inst(rc,mid+1,y,s,t,val); 41 if(tree[lc] == tree[rc]) tree[u] = tree[lc]; 42 } 43 int main() 44 { 45 int n,i,x1,x2,y1,y2; 46 scanf("%d",&n); 47 for(i = 0; i < n; i++) 48 { 49 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 50 x1 += 10001; 51 x2 += 10001; 52 y1 += 10001; 53 y2 += 10001; 54 segx[2*i] = Seg(y2,x1,x2,0); 55 segx[2*i+1] = Seg(y1,x1,x2,1); 56 segy[2*i] = Seg(x2,y1,y2,0); 57 segy[2*i+1] = Seg(x1,y1,y2,1); 58 } 59 sort(segx,segx+2*n); 60 sort(segy,segy+2*n); 61 for(i = 0; i < 2*n; i++) 62 { 63 if(segx[i].f) inst(1,1,M,segx[i].y1+1,segx[i].y2,1); 64 else inst(1,1,M,segx[i].y1+1,segx[i].y2,-1); 65 } 66 for(i = 0; i < 2*n; i++) 67 { 68 if(segy[i].f) inst(1,1,M,segy[i].y1+1,segy[i].y2,1); 69 else inst(1,1,M,segy[i].y1+1,segy[i].y2,-1); 70 } 71 printf("%d\n",ans*2); 72 return 0; 73 }