zoukankan      html  css  js  c++  java
  • UVALive

    题意:给你n个点,然后在方格纸上只能选取边或者对角线,求围住所有点的最小周长

    题解:根据样例可以发现一个规律,你把制定点的上下左右点都标出来,会发现这是围城一个点的最小距离,这样把所有的点都标记出来,求一下凸包(本人习惯kuangbin板子,但忘了凸包的时间复杂度了,以为会超时,谁知道没有),凸包的算法求出来的是点,这些点被压栈了,在计算距离的时候,只需要按照题目意思,尽量多选择对角线,连起来就可以了。

    #include <bits/stdc++.h>
    using namespace std;
    const double eps=1e-8;
    int sgn(double x)
    {
        if(fabs(x)<eps) return 0;
        if(x<0) return -1;
        else return 1;
    }
    struct point
    {
        double x,y;
        point (){}
        point (double _x,double _y)
        {
            x=_x,y=_y;
        }
        point operator -(const point &b)const
        {
            return point(x-b.x,y-b.y);
        }
        double operator ^(const point &b)const
        {
            return x*b.y-y*b.x;
        }
        double operator *(const point &b)const
        {
            return x*b.x+y*b.y;
        }
    };
    const int maxn=1e5+5;
    point List[4*maxn];
    int Stack[4*maxn],top;
    double dist(point p0,point p1)
    {
        return (double)sqrt((p0.x-p1.x)*(p0.x-p1.x)+(p0.y-p1.y)*(p0.y-p1.y));
    }
    bool cmp(point p1,point p2)
    {
        double tmp = (p1-List[0])^(p2-List[0]);
        if(sgn(tmp) > 0)return true;
        else if(sgn(tmp) == 0 && sgn(dist(p1,List[0]) - dist(p2,List[0])) <= 0)
            return true;
        else return false;
    }
    void Graham(int n)
    {
        point p0;
        int k = 0;
        p0 = List[0];
        for(int i = 1; i < n; i++){
            if((p0.y>List[i].y)||(p0.y==List[i].y&&p0.x>List[i].x)){
                p0 = List[i];
                k = i;
            }
        }
        swap(List[k],List[0]);
        sort(List+1,List+n,cmp);
        Stack[0] = 0;
        Stack[1] = 1;
        top = 2;
        for(int i = 2; i < n; i++){
            while(top > 1 &&sgn((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]]))<=0)
                    top--;
            Stack[top++] = i;
        }
    }
    point as[maxn];
    double dist2(point p0,point p1)
    {
        double as=fabs(p0.x-p1.x);
        double qw=fabs(p0.y-p1.y);
        return fabs(as-qw)+min(as,qw)*sqrt(2);
    }
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            double t1,t2;
            memset(as,0,sizeof(as));
            for(int i=0;i<n;i++){
                scanf("%lf%lf",&t1,&t2);
                as[i]=point(t1,t2);
            }
            for(int i=0;i<n;i++){
                List[4*i+0]=point(as[i].x-1,as[i].y);
                List[4*i+1]=point(as[i].x+1,as[i].y);
                List[4*i+2]=point(as[i].x,as[i].y+1);
                List[4*i+3]=point(as[i].x,as[i].y-1);
            }
            n*=4;
            Graham(n);
            double res=0.0;
            for(int i=0; i<top-1; i++)
                res+=dist2(List[Stack[i]],List[Stack[i+1]]);
            res+=dist2(List[Stack[0]],List[Stack[top-1]]);
            printf("%.4f
    ",res);
        }
        return 0;
    }
    /*
    1
    0 0
    2
    1 1
    1 2
    */
  • 相关阅读:
    image/pjpeg和image/jpeg问题
    windows server 2003 服务器中 HTTP 错误401.1 未经授权:访问由于凭据无效被拒绝
    解决了界面上菜单项跑到其它AE控件后面的问题(java)
    清除地图中的所有图层和FileFilter的使用
    设置pagelayoutControl控件显示滚动条
    pagelayoutControl中添加图元(VB)
    添加和删除字段(vb)
    用代码实现toolbar弹出ButtonMenus(VB)
    pageLayoutControl与Mapcontrol同步(VB)
    C++ Builder XE2随意学习 (1)
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/7672700.html
Copyright © 2011-2022 走看看