离散化计算重叠矩形的周长。
称平行于x轴的边为横边,我们以横边为例,某一矩形中y坐标比较小的横边我们称为始边,另一边我们称为终边。用一条扫描线从下往上扫描,当扫到一条始边的时候,如果这条始边的正下方出现过k条始边和k条终边,那么这条始边肯定是没被覆盖住的,统计结果;当扫到一条终边的时候,如果这条始边的正下方出现过k条始边和k-1条终边,同理,统计结果。
注意扫描到的边要拆成单位长度的小边分别分析。
Executing...
Test 1: TEST OK [0.005 secs, 4156 KB]
Test 2: TEST OK [0.008 secs, 4156 KB]
Test 3: TEST OK [0.016 secs, 4156 KB]
Test 4: TEST OK [0.008 secs, 4156 KB]
Test 5: TEST OK [0.016 secs, 4156 KB]
Test 6: TEST OK [0.008 secs, 4156 KB]
Test 7: TEST OK [0.043 secs, 4156 KB]
Test 8: TEST OK [0.014 secs, 4156 KB]
Test 9: TEST OK [0.019 secs, 4156 KB]
Test 10: TEST OK [0.008 secs, 4156 KB]
Test 11: TEST OK [0.103 secs, 4156 KB]
All tests OK.
Your program ('picture') produced all correct answers! This is your submission #4 for this problem. Congratulations!
1 #include <iostream> 2 #include <memory.h> 3 #include <stdio.h> 4 #include <algorithm> 5 using namespace std; 6 7 class CEdge 8 { 9 public: 10 int y; 11 int x1,x2; 12 bool isBegin; 13 CEdge(int y0=0,int x10=0,int x20=0,bool flag=false):y(y0),x1(x10),x2(x20),isBegin(flag){} 14 bool operator <(const CEdge &e2)const 15 { 16 return y<e2.y || y==e2.y && isBegin; 17 } 18 }; 19 20 int cnt[40010]={0}; 21 int n; 22 23 int solve(CEdge edges[]) 24 { 25 int ans=0; 26 memset(cnt,0,sizeof cnt); 27 28 sort(edges,edges+2*n); 29 for(int i=0;i<2*n;i++) 30 { 31 CEdge e=edges[i]; 32 for(int j=e.x1;j<e.x2;j++) 33 { 34 if(e.isBegin && cnt[j]==0 || !e.isBegin && cnt[j]==1) 35 ans++; 36 37 if(e.isBegin) 38 cnt[j]++; 39 else 40 cnt[j]--; 41 } 42 } 43 return ans; 44 } 45 46 CEdge eh[20010],ev[20010]; 47 48 int main() 49 { 50 freopen("picture.in","r",stdin); 51 freopen("picture.out","w",stdout); 52 cin>>n; 53 for(int i=0;i<n;i++) 54 { 55 int x1,y1,x2,y2; 56 scanf("%d %d %d %d",&x1,&y1,&x2,&y2); 57 x1+=10000; 58 x2+=10000; 59 y1+=10000; 60 y2+=10000; 61 62 // 加入数组 横边 63 eh[2*i]=CEdge(y1,x1,x2,true); 64 eh[2*i+1]=CEdge(y2,x1,x2,false); 65 // 加入数组 竖边 66 ev[2*i]=CEdge(x1,y1,y2,true); 67 ev[2*i+1]=CEdge(x2,y1,y2,false); 68 } 69 70 printf("%d ",solve(eh)+solve(ev)); 71 return 0; 72 }