题目大意:给你$n$个点,求出其中最远点的距离
题解:求出凸包,最远点一定都在凸包上,可以对每条边求出最远的点(可以双指针),然后求出和这条边的端点的距离,更新答案
卡点:最开始对每个点求出最远点,但这样并不可以双指针怎么搞。
C++ Code:
#include <cstdio> #include <algorithm> #define maxn 50010 int __X, __Y; inline int sqr(int x) {return x * x;} struct Point { int x, y; inline Point() {} inline Point(int __x, int __y) : x(__x), y(__y) {} inline int abs2() {return sqr(x) + sqr(y);} inline friend Point operator - (const Point &lhs, const Point &rhs) { return Point(lhs.x - rhs.x, lhs.y - rhs.y); } inline friend Point operator + (const Point &lhs, const Point &rhs) { return Point(lhs.x + rhs.x, lhs.y + rhs.y); } inline friend int operator * (const Point &lhs, const Point &rhs) { return lhs.x * rhs.y - rhs.x * lhs.y; } void writeln() { printf("(%d, %d) ", x, y); } } O, s[maxn], v[maxn]; inline int abs2(const Point &x) {return sqr(x.x) + sqr(x.y);} inline int dis2(const Point &lhs, const Point &rhs) {return abs2(lhs - rhs);} inline int det(const Point O, const Point &lhs, const Point &rhs) { return (lhs - O) * (rhs - O); } inline bool operator < (const Point &lhs, const Point &rhs) { Point X = lhs - O, Y = rhs - O; int tmp = X * Y; return (tmp > 0) || (!tmp && abs2(X) > abs2(Y)); } int n, miny, ans, tot; int main() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d%d", &s[i].x, &s[i].y); if ((s[i].y < s[miny].y) || (s[i].y == s[miny].y && s[i].x < s[miny].x)) miny = i; } if (n == 2) { printf("%d ", dis2(s[0], s[1])); return 0; } std::swap(s[0], s[miny]); O.x = s[0].x, O.y = s[0].y; std::sort(s + 1, s + n); v[tot++] = s[0], v[tot++] = s[1], v[tot++] = s[2]; for (int i = 3; i < n; i++) { for (Point a = v[tot - 2], b = v[tot - 1]; tot > 2 && det(a, b, s[i]) <= 0; a = v[tot - 2], b = v[tot - 1]) tot--; v[tot++] = s[i]; } int now = 1; for (int l = 0, r, D, tmp; l < tot; l++) { r = (l + 1) % tot; D = det(v[l], v[r], v[now]); while (D < (tmp = det(v[l], v[r], v[(now + 1) % tot]))) D = tmp, now = (now + 1) % tot; ans = std::max(ans, std::max(dis2(v[l], v[now]), dis2(v[r], v[now]))); } printf("%d ", ans); return 0; }