POJ 2187 凸包+旋转卡壳

简介:

题意:求凸包最长点对,输出两点距离的平方。

先求凸包,再旋转卡壳求直径

关于旋转卡壳的具体实现 http://www.cppblog.com/staryjy/archive/2009/11/19/101412.html

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef int PointType;
struct point
{
    PointType x,y;
    int num;
};
point data[50005],stack[51005],MinA;
int top;
PointType Direction(point pi,point pj,point pk) //判断向量PiPj在向量PiPk的顺逆时针方向 +顺-逆0共线
{
    return (pj.x-pi.x)*(pk.y-pi.y)-(pk.x-pi.x)*(pj.y-pi.y);
}
PointType Dis(point a,point b)
{
    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool cmp(point a,point b)
{
    PointType k=Direction(MinA,a,b);
    if(k>0) return 1;
    if(k<0) return 0;
    return Dis(MinA,a)>Dis(MinA,b);
}
void Graham_Scan(point *a,int numa)
{
    for(int i=0; i<numa; i++)
        if(a[i].y<a[0].y||(a[i].y==a[0].y&&a[i].x<a[0].x))
            swap(a[i],a[0]);
    MinA=a[0],top=0;
    sort(a+1,a+numa,cmp);
    stack[top++]=a[0],stack[top++]=a[1],stack[top++]=a[2];
    for(int i=3; i<numa; i++)
    {
        while(Direction(stack[top-2],stack[top-1],a[i])<0)
            top--;
        stack[top++]=a[i];
    }
}
PointType rotating_calipers(point *ch,int n)//计算凸包直径,输入凸包ch,顶点个数为n,按逆时针排列,输出直径的平方
{
    int q=1,ans=0;
    ch[n]=ch[0];
    for(int p=0; p<n; p++)
    {
        while(Direction(ch[p+1],ch[q+1],ch[p])>Direction(ch[p+1],ch[q],ch[p]))
            q=(q+1)%n;
        ans=max(ans,max(Dis(ch[p],ch[q]),Dis(ch[p+1],ch[q+1])));
    }
    return ans;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0; i<n; i++)
            scanf("%d%d",&data[i].x,&data[i].y);
        Graham_Scan(data,n);
        printf("%d\n",rotating_calipers(stack,top));
    }
    return 0;
}

目录
相关文章
HDU7018.Banzhuan(计算几何+贪心)
HDU7018.Banzhuan(计算几何+贪心)
81 0
HDU7018.Banzhuan(计算几何+贪心)
|
机器学习/深度学习
|
人工智能 SQL