题目链接:点我啊╭(╯^╰)╮
题目大意:
求二维平面内最远点距离的平方
解题思路:
最远点的距离即凸包的直径
枚举凸包的边,距离该边最远的点组成的也是最大三角形面积
根据三角形面积(对锺点)的单峰性质,可以快速找到最远点
枚举下一条边时,最远点只会继续逆时针旋转
核心:旋转卡壳
#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
const double eps = 1e-6;
const int maxn = 1e5 + 10;
int n;
struct point {
double x, y;
point() {}
point(double X, double Y) {
x = X, y = Y;
}
point operator - (const point &A) {
return point(x-A.x, y-A.y);
}
bool operator < (const point &A)const {
if(x == A.x) return y < A.y;
return x < A.x;
}
} a[maxn], pa[maxn];
int dcmp(double x) {
if(fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
double cross(point A, point B) { // 叉积
return A.x*B.y - B.x*A.y;
}
double xmult(point a, point b, point c) {
return cross(a-c, b-c);
}
double getd2(point a, point b) { // 两点距离
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}
int andrew(point *P, int n, point *S) { // P为点集合, A为凸包点
sort(P, P+n);
int tp = 0;
for(int i=0; i<n; i++) { // 下凸包
while(tp>1 && dcmp(cross(S[tp-1]-S[tp-2], P[i]-S[tp-2]))<=0) tp--;
S[tp++] = P[i];
}
for(int i=n-2, k=tp; ~i; i--) { // 上凸包
while(tp>k && dcmp(cross(S[tp-1]-S[tp-2], P[i]-S[tp-2]))<=0) tp--;
S[tp++] = P[i];
}
return n > 1 ? tp - 1 : tp;
}
int rotating_calipers(int tp) {
int q = 1;
double ret = 0;
// pa[++tp] = pa[0];
for(int i=0; i<tp; i++) {
while(xmult(pa[i], pa[i+1], pa[(q+1)%tp]) > xmult(pa[i], pa[i+1], pa[q]))
q = (q + 1) % tp;
ret = max(ret, getd2(pa[i], pa[q]));
// ret = max(ret, max(getd2(pa[i], pa[q]), getd2(pa[i+1], pa[q])));
}
return ret;
}
int main() {
scanf("%d", &n);
for(int i=0; i<n; i++) scanf("%lf%lf", &a[i].x, &a[i].y);
int tp = andrew(a, n, pa);
printf("%d\n", rotating_calipers(tp));
}