• Wall


    Wall

     

     

    题目大意:给定n个点和一个距离L,要求围墙距离任意点的距离大于等于L,求出最小围墙长度。

    最短的周长 = 凸包的周长 + 半径为L的圆的周长(顶点处加起来刚好为圆)

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <string>
     4 #include <cmath>
     5 #include <sstream>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <set>
    10 #include <map>
    11 #include <algorithm>
    12 #include <functional>
    13 using namespace std;
    14 const int maxn = 1010;
    15 const double pi=acos(-1.0);
    16 
    17 struct Point{
    18     double x,y;
    19     bool extreme;
    20     int succ;
    21 }P[maxn];
    22 int ltl;
    23 double ans;
    24 
    25 bool cmp(const Point p1, const Point p2){
    26     if( p1.y==p2.y ) return p1.x<p2.x;
    27     else return p1.y<p2.y;
    28 }
    29 
    30 bool Toleft(Point p, Point q, Point s){
    31     int area2 = p.x*q.y - p.y*q.x
    32                 + q.x*s.y - q.y*s.x
    33                 + s.x*p.y - s.y*p.x;
    34     return area2>0;///左侧为真
    35 }
    36 
    37 int LTL(Point P[], int n){
    38     int ltl=0;
    39     for(int k=1;k<n;k++){
    40         if( P[k].y<P[ltl].y || (P[k].y==P[ltl].y && P[k].x<P[ltl].x)){
    41             ltl=k;
    42         }
    43     }
    44     return ltl;
    45 }
    46 
    47 double dis(int i,int j){
    48     double xx=P[i].x-P[j].x;
    49     double yy=P[i].y-P[j].y;
    50     return sqrt(xx*xx+yy*yy);
    51 }
    52 
    53 void Jarvis(Point P[], int n){
    54     for(int k=0;k<n; k++){
    55         P[k].extreme = false;
    56     }
    57     ltl=LTL(P,n);
    58     int k=ltl;
    59     do{
    60         P[k].extreme=true;
    61         int s=-1;
    62         for(int t=0;t<n;t++){
    63             if( t!=k && t!=s && (s==-1 || Toleft(P[k],P[s],P[t]))){
    64                 s=t;
    65             }
    66         }
    67         P[k].succ = s;
    68         ans += dis(k,P[k].succ);
    69         k=s;
    70     }while(ltl!=k);
    71 }
    72 
    73 int main()
    74 {
    75     int n;
    76     double r;
    77     scanf("%d%lf",&n,&r);
    78     for(int i=0;i<n;i++){
    79         scanf("%lf%lf",&P[i].x,&P[i].y);
    80     }
    81     ans = 0.0;
    82     sort(P,P+n,cmp);///一定要排序
    83     Jarvis(P,n);
    84 //    int k=ltl;
    85 //    do{
    86 //        ans += dis(k,P[k].succ);
    87 //        k = P[k].succ;
    88 //    }while(k!=ltl);
    89 
    90     ans += 2*pi*r;
    91     printf("%.0f
    ",ans);
    92     return 0;
    93 }
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 using namespace std;
     7 typedef long long ll;
     8 const int maxn=1100;
     9 const double pi=acos(-1.0);
    10 struct node{
    11     double x,y;
    12 }p[maxn],a[maxn];
    13 int n,tot;
    14 
    15 double dis(node a, node b){
    16     return hypot(a.x-b.x,a.y-b.y);
    17 }
    18 
    19 //return 正:p2在向量p0p1的左侧;return 负:p2在向量p0p1的右侧;return 0:三点共线
    20 double multi(node p0,node p1,node p2){
    21     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    22 }
    23 //极角排序:根据坐标系内每一个点与x轴所成的角,逆时针比较,按照角度从小到大排序
    24 int cmp(node a, node b){
    25     int x=multi(a,b,p[0]);
    26     if( x>0 || (x==0&& dis(a,p[0])<dis(b,p[0]))) return 1;
    27     return 0;
    28 }
    29 
    30 void Graham(){
    31     int k=0;
    32     for(int i=1;i<n;i++){
    33         if( p[i].y<p[k].y || (p[i].y==p[k].y&&p[i].x<p[k].x)) k=i;
    34     }
    35     swap(p[0],p[k]);
    36     sort(p+1,p+n,cmp);
    37     tot=2;
    38     a[0]=p[0];
    39     a[1]=p[1];
    40     for(int i=2;i<n;i++){
    41         while( tot>1 && multi(p[i],a[tot-1],a[tot-2])>=0 ){//a[tot-2]在p[i]a[tot-1]的左侧或三点共线,则p[i]在a[tot-2]a[tot-1]的右侧,则a[tot-1]不是极点
    42             tot--;
    43         }
    44         a[tot++]=p[i];
    45     }
    46 }
    47 
    48 int main()
    49 {
    50 //    int t;
    51 //    scanf("%d",&t);
    52 //    while( t-- ){
    53         double r;
    54         scanf("%d%lf",&n,&r);
    55         for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    56         Graham();
    57         double ans=0;
    58         for(int i=0;i<tot-1;i++){
    59             ans+=dis(a[i],a[i+1]);
    60         }
    61         ans += dis(a[tot-1],a[0]);
    62         ans += 2*pi*r;
    63         printf("%.0f
    ",ans);
    64 //    }
    65     return 0;
    66 }
  • 相关阅读:
    【VC++积累】之三、操作注册表
    【网络编程】之四、socket网络编程例解
    【网络编程】之五、异步模型
    线性表5 数据结构和算法10
    单链表的删除
    单链表的插入
    单链表的插入
    单链表的插入
    线性表5 数据结构和算法10
    单链表的插入
  • 原文地址:https://www.cnblogs.com/wsy107316/p/12256885.html
Copyright © 2020-2023  润新知