首先这个题目可以用先求凸包再暴力枚举的方法通过,原因不是数据出水了,而是因为有一个奇葩的结论就是坐标值不超过K的不同的多边形最多不会超过 sqrt (K) 个 所以求出凸包后暴力枚举时间复杂度是可以接受的
- 关于多边形的切线 : 就是说一条直线与多边形相交,并且多边形在直线的一侧,这样的直线称之为多边形的切线,
关于多边形的对踵点 : 多边形的对踵点就是 : 两条平行的多边形切线上的与多边形相交的点。 对踵点有三种情况
- 两条切线都只与多边形有一个交点
- 两条切线都与多边形有无数多个交点
- 一个有一个交点,另一个有无穷多个交点
关于旋转卡壳 : 是一种求平面上所有点的最远对点的算法,我们知道可以通过求凸包 + 枚举凸包上的点的方式求出平面上所有点的最远距离,但是这种方法在凸包上的点过多的时候时间复杂度退化到 O (n ^ 2) 对于有些题目是不可以接受的,这个时候就要采取旋转卡壳的方法求平面上任意两个点的最远距离。(也叫做多边形的直径) 因为可以保证对踵点的个数不会超过 3/2n 个 所以算法的时间复杂度可以保证
- 具体实现
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 50005;
const double eps = 1e-8;
const int INF = 1e9 + 7;
struct point {
int x,y;
}p[maxn];
point poly[maxn] = {0};
point init;
int n;
int tot;
int ab (int x) {return x > 0 ? x : -x;}
int dist (point a,point b) {
return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
int cross (int x1,int y1,int x2,int y2) {
return x1 * y2 - x2 * y1;
}
bool cmp (const point a,const point b) {
if (cross(a.x - init.x,a.y - init.y,b.x - init.x,b.y - init.y) != 0) {
return cross(a.x - init.x,a.y - init.y,b.x - init.x,b.y - init.y) > 0;
}
else {
return dist (a,init) < dist (b,init);
}
}
void tubao () {
for (int i = 1;i <= 2; ++ i) poly[i] = p[i];
tot = 2;
for (int i = 3;i <= n; ++ i) {
while (tot >= 2) {
point p1,p2,p3;
p1 = poly[tot];
p2 = poly[tot - 1];
p3 = p[i];
if (cross (p1.x - p2.x,p1.y - p2.y,p3.x - p1.x,p3.y - p1.y) <= 0) tot --;
else break;
}
poly[++ tot] = p[i];
}
}
int rotating () {
if (tot == 2) return dist (poly[1],poly[2]);
poly[++tot] = poly[1];
int ans = 0;
int u = 2;
for (int i = 1;i < tot; ++ i) {
int mxd = max (dist (poly[u],poly[i]),dist (p[u],poly[i + 1]));
ans = max (ans,mxd);
while (ab (cross(poly[i].x - poly[u].x, poly[i].y - poly[u].y, poly[i + 1].x - poly[u].x, poly[i + 1].y - poly[u].y)) <= ab (cross(poly[i].x - poly[u + 1].x, poly[i].y - poly[u + 1].y, poly[i + 1].x - poly[u + 1].x, poly[i + 1].y - poly[u + 1].y))) {
u = u % tot + 1;
mxd = max (dist (poly[u],poly[i]),dist (p[u],poly[i + 1]));
ans = max (ans,mxd);
}
}
return ans;
}
int main () {
ios_base :: sync_with_stdio(false);
while (cin >> n) {
for (int i = 1;i <= n; ++ i) {
cin >> p[i].x >> p[i].y;
if (p[i].y < p[1].y) {
swap (p[1],p[i]);
}
else if (p[i].y == p[1].y && p[i].x < p[1].x) {
swap (p[1],p[i]);
}
}
if (n == 2) {
cout << dist (p[1],p[2]) << endl;
continue;
}
init = p[1];
sort (p + 1,p + n + 1,cmp);
tubao();
cout << rotating() << endl;
}
return 0;
}