zoukankan      html  css  js  c++  java
  • POJ 1113 凸包周长

    题意:

    国王想建一个周长最短的城墙,使墙的任意一点到城墙的距离都 大于 rr。求这面墙的周长。

    题解:

    凸包 水平序graham扫描法

    显然答案就是:凸包的周长+半径为rr的圆的周长

    View Code
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cstring>
     6 #include <cmath>
     7 
     8 #define N 1010
     9 #define EPS 1e-7
    10 #define PI 3.1415926535
    11 
    12 using namespace std;
    13 
    14 struct PO
    15 {
    16     double x,y;
    17 }p[N],stk[N];
    18 
    19 double rr,ans;
    20 int n;
    21 
    22 inline bool cmp(const PO &a,const PO &b)
    23 {
    24     if(a.x==b.x) return a.y<b.y;
    25     return a.x<b.x;
    26 }
    27 
    28 inline void read()
    29 {
    30     scanf("%d%lf",&n,&rr);
    31     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    32 }
    33 
    34 inline double cross(const PO &o,const PO &a,const PO &b)
    35 {
    36     return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
    37 }
    38 
    39 inline double get_dis(const PO &a,const PO &b)
    40 {
    41     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    42 }
    43 
    44 inline void graham()
    45 {
    46     sort(p+1,p+1+n,cmp);
    47     int top=0;
    48     for(int i=1;i<=n;i++)
    49     {
    50         while(top>=2&&cross(stk[top-1],stk[top],p[i])<-EPS) top--;//cross()==0时不能弹栈! 
    51         stk[++top]=p[i];
    52     }
    53     for(int i=n-1;i>=1;i--)
    54     {
    55         while(top>=2&&cross(stk[top-1],stk[top],p[i])<-EPS) top--;
    56         stk[++top]=p[i];
    57     }
    58     ans=0.0;
    59     for(int i=1;i<top;i++) ans+=get_dis(stk[i],stk[i+1]);
    60 }
    61 
    62 inline void go()
    63 {
    64     graham();
    65     ans+=2.0*rr*PI;
    66     printf("%.0lf\n",ans+EPS);
    67 }
    68 
    69 int main()
    70 {
    71     read(),go();
    72     return 0;
    73 }

     特别说明:

    一般的我们求的凸包是使其中的点尽量少,也就是说,若多点共线,只保留两个端点,判断的时候就是叉积等于0时也弹栈,但是这样会有bug

    当叉乘的两个向量相反时,就会弹栈,出现错误!

    样例真良心,样例就能拍出这个错!

    又写了一个优化的:

    View Code
     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <cstring>
     6 #include <cmath>
     7 
     8 #define N 1010
     9 #define EPS 1e-7
    10 #define PI 3.1415926535
    11 
    12 using namespace std;
    13 
    14 struct PO
    15 {
    16     double x,y;
    17 }p[N];
    18 
    19 double rr,ans;
    20 int n,stk[N];
    21 
    22 inline bool cmp(const PO &a,const PO &b)
    23 {
    24     if(a.x==b.x) return a.y<b.y;
    25     return a.x<b.x;
    26 }
    27 
    28 inline void read()
    29 {
    30     scanf("%d%lf",&n,&rr);
    31     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    32 }
    33 
    34 inline double cross(const PO &o,const PO &a,const PO &b)
    35 {
    36     return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);
    37 }
    38 
    39 inline double get_dis(const PO &a,const PO &b)
    40 {
    41     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    42 }
    43 
    44 inline void graham()
    45 {
    46     sort(p+1,p+1+n,cmp);
    47     int top=0;
    48     stk[++top]=1; stk[++top]=2;
    49     for(int i=3;i<=n;i++)
    50     {
    51         while(top>=2&&cross(p[stk[top-1]],p[stk[top]],p[i])<EPS) top--; 
    52         stk[++top]=i;
    53     }
    54     int num=top;
    55     for(int i=n-1;i>=1;i--)
    56     {
    57         while(top>num&&cross(p[stk[top-1]],p[stk[top]],p[i])<EPS) top--;
    58         stk[++top]=i;
    59     }
    60     ans=0.0;
    61     for(int i=1;i<top;i++) ans+=get_dis(p[stk[i]],p[stk[i+1]]);
    62 }
    63 
    64 inline void go()
    65 {
    66     graham();
    67     ans+=2.0*rr*PI;
    68     printf("%.0lf\n",ans+EPS);
    69 }
    70 
    71 int main()
    72 {
    73     read(),go();
    74     return 0;
    75 }
  • 相关阅读:
    模拟信号的优缺点分析
    PLC控制网关的功能介绍及应用领域
    LoRa无线数传终端的优势
    串口服务器厂家哪家好
    串口转以太网转换器的工作模式
    一个能手机控制水泵的无线远程开关控制器
    以太网IO模块是什么
    支持MQTT的模块有哪些
    常用正交表
    Spring Boot源码(五)以HttpEncodingAutoConfiguration【Http 编码自动配置】为例解释自动配置原理
  • 原文地址:https://www.cnblogs.com/proverbs/p/2912550.html
Copyright © 2011-2022 走看看