[日常摸鱼]POJ2187 BeautyContest-旋转卡壳
原来这个念 旋转卡qia壳ke…
题意:求平面内给定点集里的最远点对,$n \leq 5e4$
做法就是旋转卡壳啦,话说这题数据范围应该可以再大挺多的。
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; const int N=50005; struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y){} }p[N]; inline Point operator -(Point a,Point b) { return Point(a.x-b.x,a.y-b.y); } inline double cross(Point a,Point b) { return a.x*b.y-a.y*b.x; } inline double sqr2(double x){return x*x;} inline double dist(Point a,Point b) { return sqrt(sqr2(a.x-b.x)+sqr2(a.y-b.y)); } inline bool cmp(Point a,Point b) { if(a.x==b.x)return a.y<b.y; return a.x<b.x; } inline int convexHull(Point *s,int n) { sort(p+1,p+n+1,cmp); int t=0,k; for(register int i=1;i<=n;i++) { while(t>1&&cross(s[t]-s[t-1],p[i]-s[t-1])<=0)t--; s[++t]=p[i]; }k=t; for(register int i=n-1;i>=1;i--) { while(t>k&&cross(s[t]-s[t-1],p[i]-s[t-1])<=0)t--; s[++t]=p[i]; } if(n>1)t--; return t; } inline double rotatingCalipers(Point *s,int t) { int now=2;double ans=0; s[t+1]=s[1]; for(register int i=1;i<=t;i++) { while(cross(s[i+1]-s[i],s[now]-s[i])<cross(s[i+1]-s[i],s[now+1]-s[i])) now=now%t+1; ans=max(ans,dist(s[i],s[now])); } return ans; } int n,t; int main() { Point s[N];scanf("%d",&n); for(register int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y); t=convexHull(s,n);printf("%.0lf",sqr2(rotatingCalipers(s,t))); return 0; }