题意描述:
给定一个矩阵,输入为左上角和右下角,现在要计算出所有矩阵重叠之后的面积总和。
解题思路:
根据x轴或者y轴建树,不过数据如果够大,必须先离散化,利用扫描线记录当前区间已经被覆盖的长度,那么现在覆盖的长度乘以下一条线段的距离,这个面积则是我们需要累加的面积。
其中的测试数据计算过程如下:
View Code
1 #include<iostream> 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<algorithm> 5 #include<string.h> 6 using std::sort; 7 using std::unique; 8 const int N = 2222; 9 struct node 10 { 11 double y,lx,rx; 12 int s; 13 bool operator <(const node &tmp)const{ 14 return y<tmp.y; 15 } 16 }line[N<<4]; 17 double X[N<<4],sum[N<<4]; 18 int cnt[N<<4]; 19 void update(int t,int l,int r,int L,int R,int val) 20 { 21 if(L<=l&&r<=R) 22 { 23 cnt[t]+=val; 24 if(cnt[t])sum[t]=X[r+1]-X[l]; 25 else 26 if(l==r)sum[t]=0; 27 else sum[t]=sum[t<<1]+sum[t<<1|1]; 28 return ; 29 } 30 int m=(l+r)>>1; 31 if(L<=m)update(t<<1,l,m,L,R,val); 32 if(R>m)update(t<<1|1,m+1,r,L,R,val); 33 if(cnt[t])sum[t]=X[r+1]-X[l]; 34 else 35 if(l==r)sum[t]=0; 36 else sum[t]=sum[t<<1]+sum[t<<1|1]; 37 } 38 int Fin(double k,int len) 39 { 40 int l=0,r=len-1; 41 while(l<r) 42 { 43 int m=(l+r)>>1; 44 if(X[m]==k)return m; 45 if(X[m]>k)r=m-1; 46 else l=m+1; 47 } 48 return l; 49 } 50 int main() 51 { 52 int n,T=0; 53 double x1,x2,y1,y2; 54 while(scanf("%d",&n)&&n) 55 { 56 int top=0,i,j; 57 for(i=0,j=0;i<n;i++,j+=2) 58 { 59 scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); 60 X[top++]=x1,X[top++]=x2; 61 line[j].y=y1,line[j].lx=x1,line[j].rx=x2,line[j].s=1; 62 line[j+1].y=y2,line[j+1].lx=x1,line[j+1].rx=x2,line[j+1].s=-1; 63 } 64 sort(X,X+top); 65 top=unique(X,X+top)-X; 66 sort(line,line+j); 67 int l,r; 68 double answer=0; 69 memset(cnt,0,sizeof(cnt)); 70 memset(sum,0,sizeof(sum)); 71 for(int i=0;i<j-1;i++) 72 { 73 l=Fin(line[i].lx,top); 74 r=Fin(line[i].rx,top)-1; 75 if(r>=l)update(1,0,top-1,l,r,line[i].s); 76 answer+=sum[1]*(line[i+1].y-line[i].y); 77 } 78 printf("Test case #%d\nTotal explored area: %.2lf\n\n",++T,answer); 79 } 80 return 0; 81 }