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);
}

 

posted @ 2018-07-30 14:43  SiriusRen  阅读(82)  评论(0编辑  收藏  举报