题意:
给n(50000)个点,求这n个点间的最长距离。
思路:
最短距离用分治,最长距离用凸包+旋转卡壳
但是。。。卡壳暂时不会,先把凸包挂上来,计算几何啊我干!
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 50000
struct Point
{
int x, y;
void input() { scanf("%d%d",&x,&y); }
bool operator < (const Point &ob) const
{
if (y == ob.y) return x < ob.x;
return y < ob.y;
}
} p[N];
int crossPro(Point &o, Point &a, Point &b)
{
return (a.x-o.x)*(b.y-o.y) - (a.y-o.y)*(b.x-o.x);
}
int n, res[N];
int graham()
{
sort(p,p+n);
int i, len, top=1;
res[0] = 0;
res[1] = 1;
for (i = 2; i < n; ++ i)
{
while (top && crossPro(p[res[top-1]], p[res[top]], p[i]) <=0)
top --;
res[++top] = i;
}
len = top;
res[++top] = n-2;
for (i = n-3; i >= 0; -- i)
{
while (top!=len && crossPro(p[res[top-1]], p[res[top]], p[i]) <= 0)
top --;
res[++top] = i;
}
return top;
}
int dist(int i, int j)
{
return ((p[i].x-p[j].x)*(p[i].x-p[j].x) + (p[i].y-p[j].y)*(p[i].y-p[j].y));
}
int getMaxDist()
{
int ans = 0, tans;
for (int i = 0; i < n; ++ i)
{
for (int j = 0; j < n; ++ j)
{
tans = dist(res[i], res[j]);
if (ans < tans) ans = tans;
}
}
return ans;
}
int main()
{
while (scanf("%d",&n) != EOF)
{
for (int i = 0; i < n; ++ i)
p[i].input();
n = graham();
printf("%d\n", getMaxDist());
}
}