zoukankan      html  css  js  c++  java
  • Codeforces Gym

    题意:给你平面上一些点,求一个凸包的最短直径

    思路:旋转卡壳,然后搞一下就行了可旋转卡壳求最远点差不多,cur带表的是求出的对锺点,然后与当前的直线p[i],p[i+1],求一下距离

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    const double eps = 1e-16;
    int sgn(double x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0)return -1;
        else return 1;
    }
    struct point
    {
        double x,y;
        point(int _x = 0,int _y = 0)
        {
            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;
        }
        void sc()
        {
            scanf("%lf%lf",&x,&y);
        }
    };
    
    struct Line
    {
        point s,e;
        Line() {}
        Line(point _s,point _e)
        {
            s = _s;
            e = _e;
        }
        pair<int,point> operator &(const Line &b)const
        {
            point res = s;
            if(sgn((s-e)^(b.s-b.e)) == 0)
            {
                if(sgn((s-b.e)^(b.s-b.e)) == 0)
                    return make_pair(0,res);
                else return make_pair(1,res);
            }
            double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
            res.x += (e.x-s.x)*t;
            res.y += (e.y-s.y)*t;
            return make_pair(2,res);
        }
    };
    double dist(point a,point b)
    {
        return (double)sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    point NearestpointToLineSeg(point P,Line L)
    {
        point result;
        double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));
        if(t >= 0.000 && t <= 1.0000)
        {
            result.x = L.s.x + (L.e.x - L.s.x)*t;
            result.y = L.s.y + (L.e.y - L.s.y)*t;
        }
        else
        {
            if(dist(P,L.s) < dist(P,L.e))
                result = L.s;
            else result = L.e;
        }
        return result;
    }
    double emmm(point P,Line L)
    {
        point zz=NearestpointToLineSeg(P,L);
        return dist(zz,P);
    }
    const int MAXN = 2e5+7;
    point List[MAXN];
    int Stack[MAXN],top;
    bool _cmp(point p1,point p2)
    {
        double tmp = (p1-List[0])^(p2-List[0]);
        if(tmp > 0)return true;
        else if(tmp == 0 && dist(p1,List[0]) <= dist(p2,List[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);
        if(n == 1)
        {
            top = 1;
            Stack[0] = 0;
            return;
        }
        if(n == 2)
        {
            top = 2;
            Stack[0] = 0;
            Stack[1] = 1;
            return;
        }
        Stack[0] = 0;
        Stack[1] = 1;
        top = 2;
        for(int i = 2; i < n; i++)
        {
            while(top > 1 &&
                    ((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]])) <= 0)
                top--;
            Stack[top++] = i;
        }
    }
    double rotating_calipers(point p[],int n)
    {
        double ans = 999999999999999999999.0;
        point v;
        int cur = 1;
        for(int i = 0; i < n; i++)
        {
            v = p[i]-p[(i+1)%n];
            while((v^(p[(cur+1)%n]-p[cur])) < 0){
                cur = (cur+1)%n;s
            }
            Line qw=Line(p[(i)%n],p[(i+1)%n]);
    //        point zz=NearestpointToLineSeg(p[cur],qw);
            double as=emmm(p[cur],qw);
            //as=max(as,zx);
            ans=min(ans,as);
    //        ans=min(ans,max(dist(p[i],p[cur]),dist(p[(i+1)%n],p[(cur+1)%n])));
        }
        return ans;
    }
    point p[MAXN];
    int main()
    {
        int n,r;
        while(~scanf("%d%d",&n,&r))
        {
    
            for(int i = 0; i < n; i++)List[i].sc();
            Graham(n);
            for(int i = 0; i < top; i++)p[i] = List[Stack[i]];
            printf("%.16f
    ",rotating_calipers(p,top));
        }
        return 0;
    }
  • 相关阅读:
    python之接口与抽象类
    python之内置函数与匿名函数
    python之常用模块
    python之块包导入
    python之协程函数、递归、二分法
    Ios证书申请流程
    VUE + vue-cli + webpack 创建新项目(2)
    VUE + vue-cli + webpack 创建新项目
    布局的几种方式(静态布局、自适应布局、流式布局、响应式布局、弹性布局)
    浅谈rem布局和vm布局
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/8973980.html
Copyright © 2011-2022 走看看