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 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”