旋转卡壳模版(求凸包直径)

#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int MAXN = 100022 << 2;

struct Point
{
    int x, y;
    Point( int x = 0, int y = 0 ):x(x), y(y) { }
};

typedef Point Vector;

Vector operator+( Vector A, Vector B )       //向量加
{
    return Vector( A.x + B.x, A.y + B.y );
}

Vector operator-( Vector A, Vector B )       //向量减
{
    return Vector( A.x - B.x, A.y - B.y );
}

Vector operator*( Vector A, double p )      //向量数乘
{
    return Vector( A.x * p, A.y * p );
}

Vector operator/( Vector A, double p )      //向量数除
{
    return Vector( A.x / p, A.y / p );
}

bool operator<( const Point& A, const Point& B )   //两点比较
{
    return A.x < B.x || ( A.x == B.x && A.y < B.y );
}

double Cross( Vector A, Vector B )   //向量叉积
{
    return A.x * B.y - A.y * B.x;
}
//求凸包
int ConvexHull( Point *p, int n, Point *ch )
{
    sort( p, p + n );
    int m = 0;
    for ( int i = 0; i < n; ++i )
    {
        while ( m > 1 && Cross( ch[m - 1] - ch[m - 2], p[i] - ch[m - 2] ) <= 0 ) --m;
        ch[m++] = p[i];
    }
    
    int k = m;
    for ( int i = n - 2; i >= 0; --i )
    {
        while ( m > k && Cross( ch[m - 1] - ch[m - 2], p[i] - ch[m - 2] ) <= 0 ) --m;
        ch[m++] = p[i];
    }
    
    if ( n > 1 ) --m;
    return m;
}
//旋转卡壳(求凸包直径复杂度o(n))
int dist( Point a, Point b )
{
    return (a.x - b.x)*(a.x - b.x)+(a.y - b.y)*(a.y - b.y);
}
int RotatingCalipers( Point *ch, int n )
{
    int q = 1;
    int ans = 0;
    for ( int i = 0; i < n; ++i )
    {
        while ( Cross( ch[i + 1] - ch[i], ch[q + 1] - ch[i] ) > Cross( ch[i + 1] - ch[i], ch[q] - ch[i] ) )
            q = ( q + 1 ) % n;
        ans = max( ans, max( dist( ch[i], ch[q] ), dist( ch[i + 1], ch[q + 1] ) ) );
    }
    return ans;
}

Point read_Point( int x, int y )
{
    return Point( x, y );
}

猜你喜欢

转载自blog.csdn.net/xiao_you_you/article/details/89711668