旋转卡壳
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <cmath>
#include <algorithm>
using namespace std;
struct point
{
int x, y;
} p[50005];
int top,sta[50005];
inline double dis(const point &a, const point &b)
{
return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
}
inline int max(int a, int b)
{
return a > b ? a : b;
}
inline int xmult(const point &p1, const point &p2,const point &p0)
{
return (p1.x - p0.x)*(p2.y - p0.y) - (p1.y - p0.y)*(p2.x - p0.x);
}
int cmp(const void *a, const void *b)
{
struct point *p1 = (struct point *)a;
struct point *p2 = (struct point *)b;
int ans = xmult(*p1, *p2, p[0]);
if(ans < 0)
return 1;
else if(ans == 0 && ((*p1).x >= (*p2).x))
return 1;
else return -1;
}
void graham(int n)
{
qsort(p +1, n - 1, sizeof(point),cmp);
int i;
sta[0] = 0, sta[1] = 1;
top = 1;
for( i = 1; i < n; i++)
{
while(top > 0 && xmult(p[sta[top]], p[i], p[sta[top-1]]) <= 0)
top--;
sta[++top] = i;
}
int temp = top;
for( i = n - 2; i >= 0; i--)
{
while(top > temp && xmult(p[sta[top]], p[i], p[sta[top-1]] )<=0)
top--;
sta[++top] = i;
}
}
int rotating_calipers()
{
int i, q = 1;
int ans = 0;
sta[top] = 0;
for( i = 0; i<top; i++)
{
while(xmult(p[sta[i+1]], p[sta[q+1]], p[sta[i]]) > xmult(p[sta[i+1]], p[sta[q]], p[sta[i]]))
q = (q + 1)%(top);
ans = max(ans, max(dis(p[sta[i]], p[sta[q]]), dis(p[sta[i+1]], p[sta[q+1]])));
}
return ans;
}
int main()
{
int i, n, leftdown;
while(scanf("%d",&n) != EOF)
{
leftdown = 0;
for( i = 0; i < n; i++)
{
scanf("%d%d",&p[i].x, &p[i].y);
if(p[i].y < p[leftdown].y || (p[i].y == p[leftdown].y && p[i].x < p[leftdown].x))
leftdown = i;
}
swap(p[0], p[leftdown]);
graham(n);
printf("%d\n",rotating_calipers());
}
return 0;
}