旋转卡壳
该算法一般用于求凸包上两点间的最大距离。
方法一:
从任意一个顶点开始,按逆时针方向计算其他每一点到该顶点的距离。使距离为一直是递增的,直到开始递减;然后记录下这一次的最大值。
然后移动为基础的那个点,从上次中断的点开始;再重复上述步骤,直到距离又递减为止。
所有的最大值即是凸包的直径。
方法二:
任意取一条边,计算每一个点到该条边的距离,直到距离开始递减;具体和方法一相似。
代码实现(凸包的周长,直径:方法二)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define maxn 50100 //the max number of the points
struct point{
double x, y;
};
point pnt[maxn]; //cin's points
point res[maxn]; //the points on convex hill
int n, l; //the number of the points
bool mult(point sp, point ep, point op){
return (sp.x - op.x) * (ep.y - op.y) >= (ep.x - op.x) * (sp.y - op.y);
} //cross project
bool operator <(const point &l, const point &r){
return l.y < r.y || (l.y == r.y && l.x < r.x);
} //cmp
int graham(point pnt[], int n, point res[]){
int i, len, top = 1;
sort(pnt, pnt + n);
if (n == 0)
return 0;
res[0] = pnt[0];
if (n == 1)
return 1;
res[1] = pnt[1];
if (n == 2)
return 2;
res[2] = pnt[2];
for (i = 2; i < n; i++){
while (top && mult(pnt[i], res[top], res[top - 1]))
top--;
res[++top] = pnt[i];
}
len = top;
res[++top] = pnt[n - 2];
for (i = n - 3; i >= 0; i--){
while (top != len && mult(pnt[i], res[top], res[top - 1]))
top--;
res[++top] = pnt[i];
}
return top;
} //to be a convex hill
double cross(point a, point b, point o){
return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
}
double dis(point &p, point &q){
double x1 = p.x - q.x, y1 = p.y - q.y;
return (x1 * x1 + y1 * y1);
} //get the distance of two points
double maxlen(point *ch, int n){ //ch is res[]'s first address , n is res[]'s lenth
int q = 1;
double ans = 0;
ch[n] = ch[0]; //let the convex fill round
for (int p = 0; p < n; p++){
while (cross(ch[p + 1], ch[q + 1], ch[p]) > cross(ch[p + 1], ch[q], ch[p])) //p,p+1 is the ver and q is the points
q = (q + 1) % n;
ans = max(ans, max(dis(ch[p], ch[q]), dis(ch[p + 1], ch[q + 1]))); //get the max lenth
}
return ans;
}
int main(){
// freopen("t.txt", "r", stdin);
while(scanf("%d", &n)!=EOF){
for (int i = 0; i < n; i++)
scanf("%lf%lf", &pnt[i].x, &pnt[i].y);
int tot = graham(pnt, n, res); //tot is the number of the points one convex hill
for (int i = 0; i < tot; i++) // 0 to tot-1 on res is the points on convex
ans += dis(res[i], res[(i + 1) % tot]); //get the while lenth of the convex
printf("%.0f\n", ans);
double tlen=maxlen(res,tot);
printf("%.0f\n",tlen);
}
return 0;
}
浙公网安备 33010602011771号