poj 2187 Beauty Contest (凸包)
题目:http://poj.org/problem?id=2187
题意:给定平面上的一些散点集,求最远两点距离的平方值。
基于水平序的Andrew算法(Graham算法的变种)
1、按照x从小到大排序(如果x相同就按照y从小到大排序),删除重复点后得到序列p1,p2,。。。。
2、把p1和p2放到凸包中。从p3开始,当新点在凸包的前进方向的左边时继续,否则依次删除最近加入凸包的点,直到新点在左边。
3、依次枚举凸包的的任意两点,求出最大距离的平方
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 const double eps=1e-6; 7 typedef struct node 8 { 9 int x,y; 10 }point; 11 int n; 12 point pt[50010]; 13 point res[50010]; 14 bool cmp(point a,point b) 15 { 16 if(a.x==b.x) 17 return a.y<b.y; 18 else 19 return a.x<b.x; 20 } 21 int dcml(double x) 22 { 23 if(fabs(x)<eps) 24 return 0; 25 if(x<0) 26 return -1; 27 else 28 return 1; 29 } 30 double dot(int x1,int y1,int x2,int y2) 31 { 32 return x1*y2-x2*y1; 33 } 34 int cross(point a,point b,point c) 35 { 36 return dcml(dot(a.x-c.x,a.y-c.y,b.x-c.x,b.y-c.y)); 37 } 38 int dist(point a,point b) 39 { 40 return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 41 } 42 int main() 43 { 44 scanf("%d",&n); 45 int i; 46 for(i=0;i<n;i++) 47 { 48 scanf("%d%d",&pt[i].x,&pt[i].y); 49 } 50 sort(pt,pt+n,cmp); 51 int m; 52 m=0; 53 for(i=0;i<n;i++) 54 { 55 while(m>1&&cross(res[m-1],pt[i],res[m-2])<=0) 56 m--; 57 res[m++]=pt[i]; 58 } 59 int k=m; 60 for(i=n-2;i>=0;i--) 61 { 62 while(m>k&&cross(res[m-1],pt[i],res[m-2])<=0) 63 m--; 64 res[m++]=pt[i]; 65 } 66 if(n>1) 67 m--; 68 int dis=0; 69 int j; 70 for(i=0;i<m;i++) 71 { 72 for(j=i+1;j<m;j++) 73 { 74 int h=dist(res[i],res[j]); 75 if(dis<h) 76 dis=h; 77 } 78 } 79 printf("%d\n",dis); 80 return 0; 81 }