【凸包+旋转卡壳】平面最远点对

题目描述

给定n个点求平面最远点对

n<=50000

题解

嘛。。。自己想练练手才写上来的。。。

不过代码没问题的啦~

就是像我在计算几何学习笔记中说的一样

先求凸包再旋转卡壳求就行了

复杂度nlogn

【数据可以再大一点的2333】

代码

//by 减维
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<bitset>
#include<set>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<ctime>
#include<algorithm>
#define ll long long
#define db double
#define inf 1<<30
#define maxn 500005
#define eps 1e-8
using namespace std;

struct node{
    db x,y;
}poi[maxn],sta[maxn];

bool cmp(node x,node y){return x.x==y.x?x.y<y.y:x.x<y.x;}
bool cm2(node x,node y){return x.x==y.x?x.y>y.y:x.x>y.x;}
node operator - (node x,node y){return (node){x.x-y.x,x.y-y.y};}
db operator * (node x,node y){return x.x*y.y-x.y*y.x;}
db dis(node x,node y){return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));}

int n,top;
db mx;

void solve()
{
    int t=0;
    sta[0]=sta[top];
    for(int i=0;i<top;++i)
    {
        while(dis(sta[i],sta[t+1])-dis(sta[i],sta[t])>-eps)t=(t+1)%top;
        mx=max(mx,dis(sta[i],sta[t]));
    }
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%lf%lf",&poi[i].x,&poi[i].y);
    sort(poi+1,poi+n+1,cmp);
    sta[++top]=poi[1],sta[++top]=poi[2];
    for(int i=3;i<=n;++i)
    {
        while((poi[i]-sta[top-1])*(sta[top]-sta[top-1])>-eps&&top>=2)top--;
        sta[++top]=poi[i];
    }
    int tt=top;
    sort(poi+1,poi+n+1,cm2);
    sta[++top]=poi[2];
    for(int i=3;i<=n;++i)
    {
        while((poi[i]-sta[top-1])*(sta[top]-sta[top-1])>-eps&&top>tt)top--;
        sta[++top]=poi[i];
    }
    top--;
    solve();
    printf("%.5lf",mx);
    return 0;
}
原文地址:https://www.cnblogs.com/rir1715/p/8136703.html