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;
}
posted @ 2012-07-31 19:33  'wind  阅读(295)  评论(0编辑  收藏  举报