Gym101635K Blowing Candles

题目链接:http://codeforces.com/gym/101635

题目大意:

  推荐一篇文章:https://blog.csdn.net/wang_heng199/article/details/74477738

  该题就是要求凸包的宽度(即平行切线间的最小距离)。

AC代码:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const double inf = 2e9;
 5 const double esp = 1e-8;
 6 int sgn(double x){
 7     if(fabs(x)<esp) return 0;
 8     if(x<0) return -1;
 9     else    return 1;
10 }
11 struct Point{
12     double x,y;
13     Point (double _x=0,double _y=0){
14         x=_x,y=_y;
15     }
16     Point operator - (const Point &b) const{
17         return Point(x-b.x,y-b.y);
18     }
19     double operator ^ (const Point &b) const {
20         return x*b.y-y*b.x;
21     }
22     double operator * (const Point &b) const {
23         return x*b.x+y*b.y;
24     }
25     void input(){
26         scanf("%lf%lf",&x,&y);
27     }
28 };
29 double dist(Point a,Point b){
30     return sqrt((a-b)*(a-b));
31 }
32 const int maxn = 2e5+5;
33 Point List[maxn];
34 int Stack[maxn],top;
35 bool _cmp(Point p1,Point p2){
36     double tmp=(p1-List[0])^(p2-List[0]);
37     if(sgn(tmp)>0)   return true;
38     else if(sgn(tmp)==0 && sgn(dist(p1,List[0])-dist(p2,List[0])) <= 0)
39         return true;
40     else
41         return false;
42 }
43 void Graham(int n){
44     Point p0=List[0];
45     int k=0;
46     for(int i=1;i<n;i++){
47         if(p0.y>List[i].y || (p0.y == List[i].y && p0.x > List[i].x)){
48             p0=List[i];
49             k=i;
50         }
51     }
52     swap(List[k],List[0]);
53     sort(List+1,List+n,_cmp);
54     if(n==1){
55         top = 1;
56         Stack[0]=0;
57         return;
58     }
59     if(n==2){
60         top=2;
61         Stack[0]=0,Stack[1]=1;
62         return;
63     }
64     Stack[0]=0,Stack[1]=1;
65     top=2;
66     for(int i=2;i<n;i++){
67         while(top>1 &&
68               (sgn((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]]))<=0))
69                 top--;
70         Stack[top++]=i;
71     }
72 }
73 double rotating_calipers(Point p[],int n){
74     double ans=inf;
75     Point v;
76     int cur=1;
77     for(int i=0;i<n;i++){
78         v=p[i]-p[(i+1)%n];
79         while(sgn(v^(p[(cur+1)%n]-p[cur]))<0)
80             cur=(cur+1)%n;
81         ans=min(ans,
82                 ((p[cur]-p[(i+1)%n])^(p[i]-p[(i+1)%n]))/(dist(p[i],p[(i+1)%n])));
83     }
84     return ans;
85 }
86 Point p[maxn];
87 int main(){
88     int N,R;
89     scanf("%d%d",&N,&R);
90     for(int i=0;i<N;i++)
91         List[i].input();
92 
93     Graham(N);
94     for(int i=0;i<top;i++)
95         p[i]=List[Stack[i]];
96     double ans=rotating_calipers(p,top);
97     printf("%.16lf\n",ans);
98     return 0;
99 }

 

 

  

posted @ 2018-04-03 18:49  Blogggggg  阅读(289)  评论(0编辑  收藏  举报