• 凸包入门(Graham扫描法)(A


    题目链接:https://cn.vjudge.net/contest/276359#problem/A

    题目大意:有一个国王,要在自己的城堡周围建立围墙,要求围墙能把城堡全部围起来,并且围墙距离城堡的距离至少为l,然后问你最小的消耗量。

    具体思路: 将围起来城堡的围墙全部往外移,求出这些点构成的凸包,然后再加上半径为l的圆的周长,这就是最终答案。

    AC代码:

     1 #include<iostream>
     2 #include<stack>
     3 #include<iomanip>
     4 #include<string>
     5 #include<stdio.h>
     6 #include<cstring>
     7 #include<iomanip>
     8 #include<cmath>
     9 #include<algorithm>
    10 using namespace std;
    11 # define ll long long
    12 const int maxn = 1e3+100;
    13 const double pi= acos(-1.0);
    14 struct node
    15 {
    16     double x,y;
    17 } p[maxn],P[maxn];
    18 int n,tot;
    19 double ans,l;
    20 double X(node A,node B,node C)//求叉积的过程
    21 {
    22     return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
    23 }
    24 double len(node A,node B)
    25 {
    26     return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    27 }
    28 bool cmp(node A,node B)
    29 {
    30     double pp=X(p[0],A,B);
    31     if(pp>0)
    32         return true;
    33     if(pp<0)
    34         return false;
    35     return len(p[0],A)<len(p[0],B);
    36 }
    37 int main()
    38 {
    39     while(~scanf("%d %lf",&n,&l))
    40     {
    41         ans=2.0*pi*l;
    42         for(int i=0; i<n; i++)
    43         {
    44             scanf("%lf %lf",&p[i].x,&p[i].y);
    45         }
    46         if(n==1)
    47         {
    48             printf("%.0lf
    ",ans);
    49         }
    50         else if(n==2)
    51         {
    52             printf("%.0lf
    ",ans+=len(p[0],p[1]));
    53         }
    54         else
    55         {
    56             for(int i=0; i<n; i++)
    57             {
    58                 if(p[i].y<p[0].y)
    59                 {
    60                     swap(p[i],p[0]);
    61                 }
    62                 else if(p[i].y==p[0].y&&p[i].x<p[0].x)
    63                 {
    64                     swap(p[i],p[0]);
    65                 }
    66             }//先把第一个点找出来
    67             sort(p+1,p+n,cmp);
    68             P[0]=p[0];
    69             P[1]=p[1];//寻找凸包的起点和终点
    70             tot=1;
    71             for(int i=2; i<n; i++)
    72             {
    73                 while(tot>0&&X(P[tot-1],P[tot],p[i])<=0)//斜率相同的时候,取较远的。
    74                     tot--;
    75                 tot++;
    76                 P[tot]=p[i];
    77             }
    78             for(int i=0; i<tot; i++)
    79             {
    80                 ans+=len(P[i],P[i+1]);
    81             }
    82             ans+=len(P[0],P[tot]);
    83             printf("%.0lf
    ",ans);
    84         }
    85     }
    86     return 0;
    87 }
    88  
  • 相关阅读:
    idea中如何配置tomcat
    onselectstart属性解决双击出现的蓝色区域
    (二十二)数组的最大值和最小值
    (二十一)数组的初始化
    (二十)两种数据类型的对比
    (十九)数组的内存分配
    (十八)数组概述
    (十六)函数的重载
    (十七)自定义函数
    (十五)函数的入栈和出栈
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262755.html
Copyright © 2020-2023  润新知