题目来源:http://poj.org/problem?id=2187
求凸包的模板题。
由于坐标值不超过M的凸多边形的顶点数只有O(M)个,因而枚举就好。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn = 5e4 + 10;
int s[maxn], cnt, n;
struct Point {
long long x, y;
bool operator<(const Point &b) const {
return y == b.y ? x < b.x : y < b.y;
}
} a[maxn];
long long direction(Point p0, Point p1, Point p2) {
return (p2.x - p1.x) * (p0.y - p1.y) - (p2.y - p1.y) * (p0.x - p1.x);
}
void graham() {
s[++cnt] = 1;
s[++cnt] = 2;
for (int i = 3; i <= n; ++i) {
while (cnt > 1 && direction(a[s[cnt - 1]], a[s[cnt]], a[i]) < 0)
--cnt;
s[++cnt] = i;
}
int t = cnt;
for (int i = n - 1; i >= 1; --i) {
while (cnt > t && direction(a[s[cnt - 1]], a[s[cnt]], a[i]) < 0)
--cnt;
s[++cnt] = i;
}
}
long long dis(int i, int j) {
return (a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y);
}
int main() {
while (~scanf("%d", &n)) {
cnt = 0;
for (int i = 1; i <= n; ++i) {
scanf("%lld%lld", &a[i].x, &a[i].y);
}
sort(a + 1, a + 1 + n);
graham();
long long ans = 0;
for (int i = 1; i <= cnt; ++i) {
for (int j = 1; j <= cnt; ++j) {
ans = max(ans, dis(s[i], s[j]));
}
}
printf("%lld\n", ans);
}
return 0;
}