解析
PS:已退役,随便写写
1.最远点对绝对在凸包上
2.充分利用凸包性质(对踵点),将
O
(
n
2
)
O(n^2)
O(n2)枚举降为
O
(
n
)
O(n)
O(n) (可利用叉积判断
h
h
h相对大小)
代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define IL inline
using namespace std;
IL int read()
{
int sum = 0;
bool f = 0;
char c = getchar();
for(; '0' > c || c > '9'; c = getchar())
if(c == '-') f = 1;
for(; '0' <= c && c <= '9'; c = getchar())
sum = sum * 10 + (c - '0');
return f ? -sum : sum;
}
struct Point
{
int x, y;
IL Point(int x_ = 0, int y_ = 0) { x = x_; y = y_; }
};
IL int Cross(const Point &a, const Point &b)
{
return a.x * b.y - a.y * b.x;
}
IL int Dis(const Point &a, const Point &b)
{
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
IL int max_(int x, int y) { return x > y ? x : y; }
int n, size;
Point num[50005], stk[50005];
IL bool cmp(const Point &p1, const Point &p2)
{
int tmp = Cross(Point(p1.x - num[1].x, p1.y - num[1].y), Point(p2.x - num[1].x, p2.y - num[1].y));
if(tmp > 0) return 1;
if(tmp < 0) return 0;
return Dis(num[1], p1) < Dis(num[1], p2);
}
IL void Graham()
{
sort(num + 2, num + n + 1, cmp);
stk[1] = num[1]; stk[2] = num[2];
size = 2;
for(int i = 3; i <= n; ++i)
{
for(; size > 1 && Cross(Point(stk[size].x - stk[size - 1].x, stk[size].y - stk[size - 1].y), Point(num[i].x - stk[size].x, num[i].y - stk[size].y)) <= 0;) --size;
stk[++size] = num[i];
}
}
IL void Solve()
{
stk[++size] = stk[1];
int ans = 0, p = 3;
Point tmp;
for(int i = 2; i <= size; ++i)
{
tmp = Point(stk[i].x - stk[i - 1].x, stk[i].y - stk[i - 1].y);
for(; Cross(tmp, Point(stk[p + 1].x - stk[i - 1].x, stk[p + 1].y - stk[i - 1].y)) > Cross(tmp, Point(stk[p].x - stk[i - 1].x, stk[p].y - stk[i - 1].y));)
{
if((++p) == size) p = 1;
}
ans = max_(ans, max_(Dis(stk[i - 1], stk[p]), Dis(stk[i], stk[p])));
}
printf("%d\n", ans);
}
int main()
{
n = read();
int p = 1;
for(int i = 1; i <= n; ++i)
{
num[i].x = read(); num[i].y = read();
if(num[i].y < num[p].y || (num[i].y == num[p].y && num[i].x < num[p].x)) p = i;
}
swap(num[p], num[1]);
Graham();
Solve();
return 0;
}