POJ 1788 Building a New Depot(计算正多边形边长)

POJ 1788 Building a New Depot(计算正多边形边长)

http://poj.org/problem?id=1788

题意: ZOJ 2157

       有一个多边形(可能是凹或凸),这个多边形的每条边都平行于坐标轴,且给出多边形所有顶点的坐标,每个顶点都是拐点(即连接该顶点的两边肯定相互垂直),现在要你输出该多边形的周长.

分析:

       由于题目给出的该多边形的限制条件:平行坐标轴,每个点都是拐点. 那么可以得出结论:

对于每个XY坐标,该坐标上多边形的顶点数目一定是偶数个.(假设x=5坐标有多个顶点,那么顶点数一定是偶数,比如2个或4个或6,不可能是奇数个)

       对于某个坐标值X(Y),如果该坐标值有偶数个点,那么该坐标上肯定有边,且从上到下相邻的两个点互连成边.如下图:

 

       对于上图,可以自己对于用例画画,验证一下.

       由上面两条结论,我们可以知道每个有多边形点的x或y坐标的边构造必然是: 坐标相邻的两个点连接成一条边即可,所以我们只要加上所有这些边即可.

       首先把所有点坐标按X值排序,算出同一X值上的所有竖直的边长.

       然后把所有点坐标按Y值排序,算出同一Y值上的所有水平的边长.

       所有边长相加输出周长即可.

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000+10;
struct Point
{
    int x,y;
}P[maxn];
bool compare_x(Point A,Point B)//升序排列
{
    return A.x<B.x || (A.x==B.x&&A.y<B.y);
}
bool compare_y(Point A,Point B)
{
    return A.y<B.y || (A.y==B.y&&A.x<B.x);
}


int main()
{
    int n;
    while(scanf("%d",&n)==1 && n)
    {
        for(int i=0;i<n;++i) scanf("%d%d",&P[i].x,&P[i].y);
        int ans=0;
        sort(P,P+n,compare_x);
        for(int i=0;i<n;)
        {
            if(P[i].x==P[i+1].x)//计算竖直边
            {
                ans += P[i+1].y-P[i].y;
                i+=2;
            }
            else ++i;
        }
        sort(P,P+n,compare_y);
        for(int i=0;i<n;)
        {
            if(P[i].y==P[i+1].y)//计算水平边
            {
                ans+= P[i+1].x-P[i].x;
                i+=2;
            }
            else ++i;
        }
        printf("The length of the fence will be %d units.\n",ans);
    }
    return 0;
}

你可能感兴趣的:(Algorithm,算法,ACM,poj,计算几何)