POJ 2187 /// 凸包入门 旋转卡壳

题目大意:

求最远点对距离

 

求凸包上的最远点对

挑战263页

#include <cstdio>
#include <string.h>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
const int N=5e5+5;
const double eps=1e-10;

int n;
double add(double a,double b) {
    if(abs(a+b)<eps*(abs(a)+abs(b))) return 0;
    return a+b;
}
struct P {
    double x,y;
    P(){};
    P(double _x,double _y):x(_x),y(_y){};
    P operator - (P p) {
        return P(add(x,-p.x),add(y,-p.y)); };
    P operator + (P p) {
        return P(add(x,p.x),add(y,p.y)); };
    P operator * (double d) {
        return P(x*d,y*d); };
    double dot(P p) {
        return add(x*p.x,y*p.y); };
    double det(P p) {
        return add(x*p.y,-y*p.x); };
}p[N];

bool cmp(const P &a,const P &b){
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
vector <P> andrew()
{
    sort(p,p+n,cmp);
    int k=0;
    vector <P> q(n*2);
    for(int i=0;i<n;i++) {
        while(k>1 && (q[k-1]-q[k-2]).det(p[i]-q[k-1])<=0) k--;
        // >0时q[k-1]才位于线段q[k-2]p[i]的左侧 形成下凸
        q[k++]=p[i];
    } /// 求下凸
    for(int i=n-2,t=k;i>=0;i--) {
        while(k>t && (q[k-1]-q[k-2]).det(p[i]-q[k-1])<=0) k--;
        q[k++]=p[i];
    } /// 求上凸
    q.resize(k-1);
    return q;
}

double dist(P a,P b) {
    return (a-b).dot(a-b);
} // 点ab距离的平方

void solve()
{
    vector <P> q=andrew();
    int n=q.size();
    if(n==2) {
        printf("%.0f\n",dist(q[0],q[1]));
        return ;
    }
    
    int i=0, j=0;
    for(int k=0;k<n;k++) {
        if(!cmp(q[i],q[k])) i=k; // 凸包的最左下
        if(cmp(q[j],q[k])) j=k; // 凸包的最右上
    }

    double ans=0;
    int si=i, sj=j;
    while(i!=sj || j!=si) { // 转半圈就能判断到所有对踵点对
        ans=max(ans,dist(q[i],q[j]));
        /*判断旋转
        <0两者未达到平行 那么先转i更易达到平行
        >0两者超过平行 那么转j更易达到平行
        */
        if((q[(i+1)%n]-q[i]).det(q[(j+1)%n]-q[j])<0)
            i=(i+1)%n;
        else j=(j+1)%n;
    }
    printf("%.0f\n",ans);
}

int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lf%lf",&p[i].x,&p[i].y);
    solve();

    return 0;
}
View Code

 

posted @ 2018-09-08 09:01  _Jessie  阅读(133)  评论(0编辑  收藏  举报