POJ 1177 Picture【矩形周长并】
题意: 给出 N 个矩形,可以相互覆盖,求所有矩形合在一起的轮廓总长度。
分析:先对所有矩形按左下角的Y 坐标排序,让矩形的所有点向 X 轴投影,记录所有的投影的X值,对X 排序,分段累加X 坐标差值;
① 如果 s[i].y1>up 说明两个矩形没有交集,即新的矩形没有被前一个矩形覆盖到 ,res+=2*(right[i]-right[i-1]) 累加新的 横边覆盖值。
② 如果 s[i].y2>up 说明新的矩形下边界在该 相邻 X 的区间被覆盖,所以只要更新给 区间的上边界 UP=s[i].y2
然后对矩形按左下角的X 坐标排序,让矩形向y轴作投影,最后按照类似的方法求出 所有竖边的和。
#include<stdio.h> #include<string.h> #include<stdlib.h> #define eps 1e-8 #define INF 0x1f1f1f int tot,n,m,tt; struct node { double x1,y1,x2,y2; }s[10005]; double left[10005]; double right[10005]; double x[10005]; double y[10005]; int cmp1(const void*p1,const void*p2) { node *a=(node*)p1; node *b=(node*)p2; return a->y1>b->y1?1:-1; } int cmp2(const void*p1,const void*p2) { node *a=(node*)p1; node *b=(node*)p2; return a->x1>b->x1?1:-1; } int cmp3(const void*p1,const void*p2) { return *(double*)p1>*(double*)p2?1:-1; } int main() { int i,j; double res,up,down; while(scanf("%d",&n)!=EOF) { tot=0; for(i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&s[i].x1,&s[i].y1,&s[i].x2,&s[i].y2); x[tot]=s[i].x1; y[tot++]=s[i].y1; x[tot]=s[i].x2; y[tot++]=s[i].y2; } res=0; qsort(s,n,sizeof(s[0]),cmp1); qsort(x,tot,sizeof(x[0]),cmp3); tt=0; for(i=1;i<tot;i++) if(x[i]!=x[i-1]) { left[tt]=x[i-1]; right[tt++]=x[i]; } for(i=0;i<tt;i++) { up=down=-INF; for(j=0;j<n;j++) if(left[i]>=s[j].x1&&right[i]<=s[j].x2) { if(s[j].y1>up) { res+=2*(right[i]-left[i]); down=s[j].y1; up=s[j].y2; } else if(s[j].y2>up) up=s[j].y2; } } qsort(s,n,sizeof(s[0]),cmp2); qsort(y,tot,sizeof(y[0]),cmp3); tt=0; for(i=1;i<tot;i++) if(y[i]!=y[i-1]) { left[tt]=y[i-1]; right[tt++]=y[i]; } for(i=0;i<tt;i++) { up=down=-INF; for(j=0;j<n;j++) if(left[i]>=s[j].y1&&right[i]<=s[j].y2) { if(s[j].x1>up) { res+=2*(right[i]-left[i]); down=s[j].x1; up=s[j].x2; } else if(s[j].x2>up) up=s[j].x2; } } printf("%.0lf",res); } return 0; }