码迷,mamicode.com
首页 > 其他好文 > 详细

UVAlive 6859 Points(凸包)

时间:2016-08-17 23:14:05      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4871

思路:将所有点上下左右四个点构成的集合求一遍凸包,边长不能直接计算(正确结果可能不为凸包)。

边长计算用下列式子:

    x=fabs(a.x-b.x)

    y=fabs(a.y-b.y)

    c=fabs(x-y)+min(x,y)*sqrt(2)

(若答案最小则应尽量选择更多斜边)

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-10;
const int maxn=4e5+50;
struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y) {}
};
typedef Point Vector;
Vector operator + (Vector A,Vector B)
{
    return Vector(A.x+B.x,A.y+B.y);
}
Vector operator - (Point A,Point B)
{
    return Vector(A.x-B.x,A.y-B.y);
}
Vector operator * (Vector A,double p)
{
    return Vector(A.x*p,A.y*p);
}
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    else return x<0?-1:1;
}
double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}
int cmp(Point a,Point b)
{
    if(a.x==b.x) return a.y<b.y;
    else return a.x<b.x;
}
int ConvexHull(Point* p,int n,Point* ch)
{
    sort(p,p+n,cmp);
    int m=0;
    for(int i=0; i<n; i++)
    {
        while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
        ch[m++]=p[i];
    }
    int k=m;
    for(int i=n-2; i>=0; i--)
    {
        while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0) m--;
        ch[m++]=p[i];
    }
    if(n>1) m--;
    return m;
}
double dist(Point a,Point b)
{
    double x=fabs(a.x-b.x);
    double y=fabs(a.y-b.y);
    return fabs(x-y)+min(x,y)*sqrt(2);
}
int n;
Point ch[maxn],p[maxn];
int main()
{
    while(scanf("%d",&n)==1)
    {
        int tot=0;
        for(int i=0; i<n; i++)
        {
            double x,y;
            scanf("%lf%lf",&x,&y);
            p[tot++]=Point(x-1,y);
            p[tot++]=Point(x+1,y);
            p[tot++]=Point(x,y+1);
            p[tot++]=Point(x,y-1);
        }
        memset(ch,0,sizeof(ch));
        double ans=0.0;
        int num=ConvexHull(p,tot,ch);
        for(int i=0;i<num;i++)
            ans+=dist(ch[i],ch[(i+1)%num]);
        printf("%.4f\n",ans);
    }
    return 0;
}



UVAlive 6859 Points(凸包)

标签:

原文地址:http://blog.csdn.net/wang2147483647/article/details/52234974

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!