• Wall


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348

    题意:给定多边形城堡的n个顶点,绕城堡外面建一个围墙,围住所有点,并且墙与所有点的距离至少为L,求这个墙最小的长度。

    思路:如果没有"墙与所有点的距离至少为L"这个条件就只要求一个凸包,再求凸包的周长即可。墙与所有点的距离至少为L,其实只要在凸包的周长上再加一个半径为L的圆周长即可。

    在vj上一直过不了,杭电oj就能过。吐了。

    #include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const double PI = atan(1.0)*4.;
    const int maxn=200005;
    struct point
    {
        double x,y;
        point friend operator -(point A,point B)
        {
            return {A.x-B.x,A.y-B.y};
        }
    };
    struct line
    {
        point x,y;
    };
    point p[maxn];//输入点集
    point q[maxn];//凸包点集
    double dis(point A,point B)//两点的距离
    {
        return sqrt( (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y) );
    }
    double chaj(point A,point B)//差积
    {
        return A.x*B.y-A.y*B.x;
    }
    bool cmp(point A,point B)//以p[0]为起点,按差积逆时针排序
    {
        double s=chaj(A-p[1],B-p[1]);
        if(s>0)
            return true;
        if(s==0)
            return dis(A,p[1])<dis(B,p[1]);
        return false;
    }
    double perimeter(int len)//凸包求周长
    {
        double sum=0;
        for(int i=2; i<=len; i++)
            sum+=dis(q[i-1],q[i]);
        return sum+dis(q[1],q[len]);
    }
    int main()
    {
        int t,u=0;
        cin>>t;
        while(t--)
        {
            if(u>0)
                cout<<endl;
            u++;
            int N,M;
            cin>>N>>M;
            for(int i=1; i<=N; i++)
                cin>>p[i].x>>p[i].y;
            //找到最小的点
            int K=1;
            for(int i=2; i<=N; i++)
            {
                if(p[i].y<p[K].y||(p[i].y==p[K].y&&p[i].x<p[K].x))
                    K=i;
            }
            swap(p[1],p[K]);
    
            sort(p+2,p+1+N,cmp);
    
            q[1]=p[1];
            q[2]=p[2];
            int len=2;//凸包点的个数
            for(int i=3; i<=N; i++)
            {
                while(len>=2&&chaj(q[len]-q[len-1],p[i]-q[len-1])<=0)
                    len--;
                q[++len]=p[i];
            }
            double sum=2*M*PI;
            printf("%.lf
    ",perimeter(len)+sum);//周长
        }
    }
  • 相关阅读:
    Excel导出
    上传进度基础
    git基本使用
    git学习记录
    Composer 扩展包安装方法
    selected多次点击不生效
    ajaxFileUpload的data数据带pre标签
    php-resque 简单的php消息队列
    git checkout 报错 refname 'origin/branch-name' is ambiguous
    MySQL单独存放表空间Innodb_file_per_table
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/13781747.html
Copyright © 2020-2023  润新知