#include<stdio.h> #include<algorithm> using namespace std;
const int Maxn=5000; struct rectangle { int x1,x2,y1,y2; }rec[Maxn]; int horizontal[Maxn*2],vertical[Maxn*2],record[Maxn*2]; int n;
int cmp(const void *a,const void *b) { return *(int *)a-*(int *)b; }
int lookup(int s[],int key) { int begin=0,end=2*n-1,middle; while(begin<=end) { middle=(begin+end)/2; if(s[middle]==key) return middle; else if(s[middle]>key) end=middle-1; else begin=middle+1; } }
int count_x(int x1,int x2) { int i; for(i=0;i<n;i++) { if(x1>=rec[i].x1&&x2<=rec[i].x2) //该矩形横跨了该组超元线段
{ record[lookup(vertical,rec[i].y2)]++; record[lookup(vertical,rec[i].y1)]--; } } int sum=0,add=0; for(i=0;i<2*n;i++) { if(record[i]!=0) { if(add==0) sum++; add+=record[i]; if(add==0) sum++; } } return sum; }
int count_y(int y1,int y2) { int i; for(i=0;i<n;i++) { if(rec[i].y1<=y1&&rec[i].y2>=y2) { record[lookup(horizontal,rec[i].x2)]++; record[lookup(horizontal,rec[i].x1)]--; } } int sum=0,add=0; for(i=0;i<2*n;i++) { if(record[i]!=0) { if(add==0) sum++; add+=record[i]; if(add==0) sum++; } } return sum; }
int main() { scanf("%d",&n); int i; for(i=0;i<n;i++) { scanf("%d%d%d%d",&rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2); horizontal[i*2]=rec[i].x1;horizontal[i*2+1]=rec[i].x2; vertical[i*2]=rec[i].y1;vertical[i*2+1]=rec[i].y2; }
qsort(horizontal,n*2,sizeof(int),cmp); qsort(vertical,n*2,sizeof(int),cmp);
int length,amount,perimeter=0; for(i=0;i<n*2-1;i++) { length=horizontal[i+1]-horizontal[i]; if(length!=0) { memset(record,0,sizeof(record)); ///记录矩形的上下两边横跨超元线段的情况
amount=count_x(horizontal[i],horizontal[i+1]); perimeter+=length*amount; } }
for(i=0;i<n*2-1;i++) { length=vertical[i+1]-vertical[i]; if(length!=0) { memset(record,0,sizeof(record)); ///记录矩形的左右两边横跨超元线段的情况
amount=count_y(vertical[i],vertical[i+1]); perimeter+=length*amount; } }
printf("%d\n",perimeter); return 0; }
|