旋转卡壳
Smiling & Weeping
---- 一个能升起月亮的身体,必然驮住了无数次日落
题目链接:https://www.luogu.com.cn/problem/P1452
题目简介:
# [USACO03FALL] Beauty Contest G /【模板】旋转卡壳
## 题目描述
给定平面上 $n$ 个点,求凸包直径。
## 输入格式
第一行一个正整数 $n$。
接下来 $n$ 行,每行两个整数 $x,y$,表示一个点的坐标。
## 输出格式
输出一行一个整数,表示答案的平方。
## 样例 #1
### 样例输入 #1
```
4
0 0
0 1
1 1
1 0
```
### 样例输出 #1
```
2
```
## 提示
【数据范围】
对于 $100\%$ 的数据,$2\le n \le 50000$,$|x|,|y| \le 10^4$。
Talk is cheap , show me the code
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5+1; 4 const double eps=1e-6; 5 int n; 6 int sgn(double x){ 7 if(fabs(x)<eps) return 0; 8 else 9 return x<0 ? -1 : 1; 10 } 11 struct Point{ 12 double x , y; 13 Point() {} 14 Point(double x , double y) : x(x),y(y) {} 15 Point operator + (Point b) {return Point(x+b.x , y+b.y); } 16 Point operator - (Point b) {return Point(x-b.x , y-b.y); } 17 bool operator == (Point b) {return sgn(x-b.x)==0 && sgn(y-b.y)==0; } 18 bool operator < (const Point& b){ 19 return sgn(x-b.x)<0 || (sgn(x-b.x)==0 && sgn(y-b.y)<0); 20 } 21 }; 22 typedef Point Vector; 23 double Cross(Vector a , Vector b){ 24 return a.x*b.y-a.y*b.x; 25 } 26 vector<Point> v; // 存所有点,并进行从小到大排序 27 double line[N],ptr=0; // 保存半个凸壳的路径 28 vector<Point> hull; // 保存完整凸壳的路径 29 Point p[N],ch[N]; 30 int convex() // 求凸壳 31 { 32 sort(p,p+n); 33 n = unique(p,p+n)-p; 34 int u=0; 35 for(int i = 0; i < n; i++){ 36 while(u>1 && sgn(Cross(ch[u-1]-ch[u-2] , p[i]-ch[u-1]))<=0) 37 u--; 38 ch[u++]=p[i]; 39 } 40 int j = u; 41 for(int i = n-2; i >= 0; i--){ 42 while(u>j && sgn(Cross(ch[u-1]-ch[u-2],p[i]-ch[u-1]))<=0) 43 u--; 44 ch[u++]=p[i]; 45 } 46 if(n>1) u--; 47 return u; 48 } 49 double Distance(Point& a , Point& b){ 50 return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); 51 } 52 double rotateCalipers(int len){ 53 double ans = -1; 54 int size = len; 55 int op = 1; // 对面的点,逆时针沿凸包移动 56 Point p1,p2; 57 for(int i = 0; i < size; i++){ 58 p1 = ch[i]; p2 = ch[(i+1)%size]; 59 while(Cross(p2-ch[(op+1)%size],p1-ch[(op+1)%size]) < Cross(p2-ch[op] , p1-ch[op])) 60 op = (op+1)%size; 61 ans = max(ans , max(Distance(p1 , ch[op]) , Distance(p2 , ch[op]))); 62 } 63 return ans; 64 } 65 int main() 66 { 67 double x,y; 68 scanf("%d",&n); 69 for(int i = 0; i < n; i++){ 70 scanf("%lf %lf",&x,&y); 71 p[i] = Point(x,y); 72 } 73 int len = convex(); 74 printf("%d\n",(int)rotateCalipers(len)); 75 return 0; 76 }
借我一个暮年,
借我碎片,
借我踌躇满志,借我一生有梦
文章到此结束,我们下次再见