POJ 2187 凸包+旋转卡壳
思路:
求个凸包
旋转卡壳一下
就求出来最远点对了
注意共线情况
也就是说 凸包如果有一堆点共线保留端点即可
//By SiriusRen #include <cmath> #include <cstdio> #include <algorithm> using namespace std; const int N=100050; int n,k,top,now=2,ans; struct P{int x,y;P(){}P(int X,int Y){x=X,y=Y;}}p[N],tb[N]; bool cmp(P a,P b){return a.x==b.x?a.y<b.y:a.x<b.x;} int operator*(P a,P b){return a.x*b.y-a.y*b.x;} P operator-(P a,P b){return P(a.x-b.x,a.y-b.y);} int cross(P a,P b,P c){return (a-c)*(b-c);} int dis(P a){return a.x*a.x+a.y*a.y;} int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y); sort(p+1,p+1+n,cmp); for(int i=1;i<=n;i++){ while(top>1&&cross(tb[top],p[i],tb[top-1])<=0)top--; tb[++top]=p[i]; }k=top; for(int i=n-1;i;i--){ while(top>k&&cross(tb[top],p[i],tb[top-1])<=0)top--; tb[++top]=p[i]; } for(int i=1;i<top;i++){ while((tb[i+1]-tb[i])*(tb[now]-tb[i])<(tb[i+1]-tb[i])*(tb[now+1]-tb[i])){ now++;if(now==top)now=1; }ans=max(ans,dis(tb[i]-tb[now])); }printf("%d\n",ans); }