求凸包上最远两点距离的平方值

来源:互联网 发布:百度seo排名点击软件 编辑:程序博客网 时间:2024/04/18 19:45



#include <iostream>#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cmath>using namespace std;typedef long long LL;const double INF = 1e18+5;const int MAXN = 1e6 + 5;const double eps = 1e-10;const double PI = acos(-1.0);int double_cmp(double x){    if(fabs(x) < eps)        return 0;    if(x > 0)        return 1;    return -1;}struct Point{    double x, y;    int id;    Point() {}    Point (double _x, double _y, int i):x(_x),y(_y),id(i) {}    bool operator <(const struct Point &tmp)const    {        if(double_cmp(x-tmp.x) == 0)            return double_cmp(y-tmp.y) < 0;        return double_cmp(x-tmp.x) < 0;    }    bool operator == (const struct Point &tmp)const    {        return double_cmp(x-tmp.x)==0&&double_cmp(y-tmp.y)==0;    }} p[MAXN],st[MAXN];double XMulti(Point a, Point b, Point c)///ac X ab{    return (c.x-a.x)*(b.y-a.y) - (b.x-a.x)*(c.y-a.y);}double dis(Point a, Point b){    return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));}double dis2(Point a, Point b){    return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);}double dot(Point a, Point b, Point c)///点积 ab . ac{    double s1 = b.x-a.x;    double t1 = b.y-a.y;    double s2 = c.x-a.x;    double t2 = c.y-a.y;    return s1*s2 + t1*t2;}int ConvexHull(Point *p, int n, Point *st)///凸包,返回凸包顶点个数{    sort(p, p+n);    n = unique(p, p+n)-p;///去重    int m = 0;    for(int i=0; i<n; i++)    {        while(m>1 && XMulti(st[m-2],p[i],st[m-1])<=0)            m--;        st[m++] = p[i];    }    int k = m;    for(int i=n-2; i>=0; i--)    {        while(m>k && XMulti(st[m-2],p[i],st[m-1])<=0)            m--;        st[m++] = p[i];    }    if(n > 1)        m--;    return m;}double rotating_calipers(Point *p, int n)///旋转卡壳求凸包的直径,平面最远的点对{    int k=1;    double ans = 0;    p[n]=p[0];    for(int i=0; i<n; i++)    {        while(fabs(XMulti(p[i+1],p[k],p[i]))<fabs(XMulti(p[i+1],p[k+1],p[i])))            k=(k+1)%n;        ans = max(ans,max(dis2(p[i],p[k]),dis2(p[i+1],p[k])));///注意是用的函数dis2    }    return ans;}int main(){    int n;    while(cin>>n)    {        for(int i=0; i<n; i++)        {            cin>>p[i].x>>p[i].y;        }        int m = ConvexHull(p, n, st);        cout<<"m="<<m<<endl;        double ans = rotating_calipers(st, m);        printf("%0.0lf\n",ans);    }    return 0;}


0 0