求平面最大点对。
找凸包 -> 根据凸包运用旋转卡壳算法求最大点对(套用kuang巨模板)
#include<bits/stdc++.h> using namespace std; struct point { int x,y; point operator -(const point& rhs)const { point ret; ret.x=x-rhs.x; ret.y=y-rhs.y; return ret; } int operator *(const point& rhs)const//叉乘 { return x*rhs.y-y*rhs.x; } bool operator <(const point& rhs)const { return x<rhs.x||x==rhs.x&&y<rhs.y; } } p[100005],s[100005]; int top; bool ok(point A,point B,point C) //判断ABC是否是按逆时针顺序给出 { return (B-A)*(C-A)>0; } int dist2(point a,point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } int rotating_calipers() { int ret = 0; point v; int cur = 1; for(int i = 0; i < top; i++) { v = s[i]-s[(i+1)%top]; while((v*(s[(cur+1)%top]-s[cur])) < 0) cur = (cur+1)%top; ret = max(ret,max(dist2(s[i],s[cur]),dist2(s[(i+1)%top],s[(cur+1)%top]))); } return ret; } int main() { int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=0; i<n; i++) scanf("%d%d",&p[i].x,&p[i].y); sort(p,p+n); top=0; for(int i=0; i<n; i++) //求下凸包 { while(top>=2 && !ok(s[top-2],s[top-1],p[i])) top--; s[top++]=p[i]; } int t=top-1; for(int i=n-1; i>=0; i--) //求上凸包 { while(top>=t+2 && !ok(s[top-2],s[top-1],p[i])) top--; s[top++]=p[i]; } --top; // 首尾点相同,故舍去 int ans=rotating_calipers(); printf("%d\n",ans); } }
时间: 2024-10-29 19:06:19