zoukankan      html  css  js  c++  java
  • bzoj1670【Usaco2006 Oct】Building the Moat 护城河的挖掘

    1670: [Usaco2006 Oct]Building the Moat护城河的挖掘

    Time Limit: 3 Sec  Memory Limit: 64 MB
    Submit: 387  Solved: 288
    [Submit][Status][Discuss]

    Description

    为了防止口渴的食蚁兽进入他的农场,Farmer John决定在他的农场周围挖一条护城河。

    农场里一共同拥有N(8<=N<=5,000)股泉水,而且,护城河总是笔直地连接在河道上的相邻的两股泉水。护城河必须能保护全部的泉水,也就是说,能包围全部的泉水。泉水一定在护城河的内部,或者恰好在河道上。当然。护城河构成一个封闭的环。

    挖护城河是一项昂贵的project,于是,节约的FJ希望护城河的总长度尽量小。

    请你写个程序计算一下,在满足需求的条件下,护城河的总长最小是多少。 全部泉水的坐标都在范围为(1..10,000,000,1..10,000,000)的整点上,一股泉水相应着一个唯一确定的坐标。而且,随意三股泉水都不在一条直线上。

    下面是一幅包括20股泉水的地图,泉水用"*"表示


    图中的直线,为护城河的最优挖掘方案。即能围住全部泉水的最短路线。 路线从左上角起,经过泉水的坐标依次是:(18,0),(6,-6),(0,-5),(-3,-3),(-17,0),(-7,7),(0,4),(3,3)。绕行一周的路径总长为70.8700576850888(...)。答案仅仅须要保留两位小数,于是输出是70.87。

    Input

    * 第1行: 一个整数,N * 第2..N+1行: 每行包括2个用空格隔开的整数。x[i]和y[i],即第i股泉水的位 置坐标 

    Output

    * 第1行: 输出一个数字。表示满足条件的护城河的最短长度。保留两位小数 

    Sample Input

    20
    2 10
    3 7
    22 15
    12 11
    20 3
    28 9
    1 12
    9 3
    14 14
    25 6
    8 1
    25 1
    28 4
    24 12
    4 15
    13 5
    26 5
    21 11
    24 4
    1 8

    Sample Output

    70.87

    HINT

    Source




    凸包模板题




    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #define F(i,j,n) for(int i=j;i<=n;i++)
    #define D(i,j,n) for(int i=j;i>=n;i--)
    #define ll long long
    #define maxn 5005
    using namespace std;
    int n,top;
    double ans;
    struct P{int x,y;}p[maxn],s[maxn];
    inline int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    	while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    inline P operator-(const P &a,const P &b)
    {
    	return (P){a.x-b.x,a.y-b.y};
    }
    inline ll operator*(const P &a,const P &b)
    {
    	return a.x*b.y-a.y*b.x;
    }
    inline ll dis(P a,P b)
    {
    	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }
    inline bool operator<(const P &a,const P &b)
    {
    	ll t=(a-p[1])*(b-p[1]);
    	if (t==0) return dis(p[1],a)<dis(p[1],b);
    	else return t<0;
    }
    inline void solve()
    {
    	int t=1;
    	F(i,2,n) if (p[i].y<p[t].y||(p[i].y==p[t].y&&p[i].x<p[t].x)) t=i;
    	swap(p[1],p[t]);
    	sort(p+2,p+n+1);
    	s[++top]=p[1];s[++top]=p[2];
    	F(i,3,n)
    	{
    		while (top>=2&&(s[top]-s[top-1])*(p[i]-s[top-1])>=0) top--;
    		s[++top]=p[i];
    	}
    	s[top+1]=p[1];
    	F(i,1,top) ans+=sqrt(dis(s[i],s[i+1]));
    }
    int main()
    {
    	n=read();
    	F(i,1,n) p[i].x=read(),p[i].y=read();
    	solve();
    	printf("%.2lf
    ",ans);
    	return 0;
    }
    


  • 相关阅读:
    react axios 跨域访问一个或多个域名
    基础复习1
    Webpack笔记
    小程序笔记下
    小程序笔记上
    webpack-dev-server的使用
    webpack资源加载常用配置
    vue实现组件切换的两种方式
    vue实现一个评论列表
    子组件调用父组件的数据及方法
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7263030.html
Copyright © 2011-2022 走看看