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


    Time Limit: 3 Sec  Memory Limit: 64 MB
    Submit: 347  Solved: 255
    [Submit][Status][Discuss]

    Description

    为了防止口渴的食蚁兽进入他的农场,Farmer John决定在他的农场周围挖一条护城河。农场里一共有N(8<=N<=5,000)股泉水,并且,护城河总是笔直地连接在河道上的相邻的两股泉水。护城河必须能保护所有的泉水,也就是说,能包围所有的泉水。泉水一定在护城河的内部,或者恰好在河道上。当然,护城河构成一个封闭的环。 挖护城河是一项昂贵的工程,于是,节约的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
    题解:
      一道裸的求凸包周长。讲解:Graham's Scan法求解凸包问题
      旋转卡壳,有待学习。
     1 #include<cstring>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<cstdio>
     5 #include<algorithm>
     6 
     7 #define N 5007
     8 #define ll long long
     9 using namespace std;
    10 inline int read()
    11 {
    12     int x=0,f=1;char ch=getchar();
    13     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
    14     while(ch<='9'&&ch>='0')
    15     {
    16         x=(x<<3)+(x<<1)+ch-'0';
    17         ch=getchar();
    18     }
    19     return x*f;
    20 }
    21 
    22 int n,top;
    23 struct Node
    24 {
    25     int x,y;
    26 }a[N],b[N];
    27 double ans=0;
    28 
    29 inline ll sqr(ll x){return x*x;}
    30 inline Node operator-(Node x,Node y){return (Node){x.x-y.x,x.y-y.y};}
    31 inline ll operator*(Node x,Node y){return x.x*y.y-x.y*y.x;}
    32 inline ll dis(Node x,Node y)
    33 {
    34     return sqr(x.x-y.x)+sqr(x.y-y.y);
    35 }
    36 bool cmp(Node x,Node y)
    37 {
    38     ll t=(x-a[1])*(y-a[1]);
    39     if (t==0) return dis(a[1],x)<dis(a[1],y);
    40     return t>0;
    41 }
    42 void graham()
    43 {
    44     int t=1;
    45     for (int i=2;i<=n;i++)
    46         if (a[i].y<a[t].y||(a[i].y==a[t].y&&a[i].x<a[t].x)) t=i;//平面直角坐标系里最左下那个点。
    47     swap(a[1],a[t]);
    48     sort(a+2,a+n+1,cmp);     
    49     b[++top]=a[1],b[++top]=a[2];
    50     for (int i=3;i<=n;i++)
    51     {
    52         while((b[top]-b[top-1])*(a[i]-b[top-1])<=0) top--;
    53         b[++top]=a[i];
    54     }
    55     b[top+1]=a[1];
    56     for (int i=1;i<=top;i++)
    57         ans+=sqrt(dis(b[i],b[i+1]));
    58 }
    59 int main()
    60 {
    61     n=read();
    62     for (int i=1;i<=n;a[i].x=read(),a[i].y=read(),i++);
    63     graham();
    64     printf("%.2lf
    ",ans);
    65 }
     
  • 相关阅读:
    java之this关键字
    单位转换类UnitUtil2
    重量WeightFormatUtil辅助类
    语音提示辅助类MySoundAlertUtil
    Android 编程下 Touch 事件的分发和消费机制
    switch case语句的用法
    Struts2之环境配置
    CSS属性绘制图形(一)
    jquery $(document).ready() 与window.onload的区别
    Android开发之ActionBar
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8005556.html
Copyright © 2020-2023  润新知