【凸包+旋转卡壳】平面最远点对
题目描述
给定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; }