凸包 + 枚举。
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 8 using namespace std; 9 10 typedef struct node 11 { 12 int x, y; 13 }node; 14 15 node f[50002]; 16 17 bool cmp(node a,node b) //叉积排序 如果相等 近的优先 18 { 19 if((a.x-f[0].x)*(b.y-f[0].y) == (b.x-f[0].x)*(a.y-f[0].y)) 20 return ((a.x-f[0].x)*(a.x-f[0].x)+(a.y-f[0].y)*(a.y-f[0].y)) 21 < ((f[0].x-b.x)*(f[0].x-b.x)+(f[0].y-b.y)*(f[0].y-b.y)); 22 return (a.x-f[0].x)*(b.y-f[0].y) > (b.x-f[0].x)*(a.y-f[0].y); 23 } 24 25 bool left(int i, int j, int k) //判断是否左转 26 { 27 int x1=f[j].x-f[i].x; 28 int y1=f[j].y-f[i].y; 29 int x2=f[k].x-f[j].x; 30 int y2=f[k].y-f[j].y; 31 if (x1*y2 > x2*y1) //这种情况为不要直线上多余的点 如果想要应用 >= 32 return true; 33 return false; 34 } 35 36 int dis(int i, int j) //求两点距离平方 37 { 38 return (f[i].x-f[j].x)*(f[i].x-f[j].x) 39 +(f[i].y-f[j].y)*(f[i].y-f[j].y); 40 } 41 42 int main() 43 { 44 int n, i, j, k; 45 int st[50002]; //储存凸包顶点 46 while(scanf("%d", &n)!=EOF) 47 { 48 k=0; 49 for (i=0; i<n; i++) 50 { 51 scanf("%d%d", &f[i].x, &f[i].y); 52 if (f[i].y < f[k].y || (f[i].y==f[k].y && f[i].x <f[k].x)) 53 k=i; 54 } 55 if (k != 0) 56 { 57 swap(f[0].x, f[k].x); 58 swap(f[0].y, f[k].y); 59 } 60 sort(f+1, f+n, cmp); 61 int top=0; 62 st[top++]=0; 63 st[top++]=1; 64 st[top++]=2; 65 for (i=3; i<n; ) 66 { 67 if (top < 2 || left(st[top-2], st[top-1], i)) //是左转则入栈加一 (top<2)的情况是对于开始就有直线又不要直线上多余点的情况, 68 st[top++]=i++; //防止越界。如果直线上多余的点也要则可不写,但会有多余的点使得效率低 69 else 70 top--; 71 } 72 st[top]=st[0]; 73 int d=0; 74 for (i=0; i<top; i++) //枚举求最大距离平方 75 { 76 for (j=i+1; j<top; j++) 77 { 78 if (d < dis(st[i], st[j])) 79 d=dis(st[i], st[j]); 80 } 81 } 82 printf("%d\n", d); 83 } 84 return 0; 85 }