观察数据范围,发现可以接受的复杂度在O(n^2log)
考虑枚举四边形对角线,那么分别找到离对角线两边离他最远的点即可.
先求出所有点构成的凸包,然后用旋转卡壳求出最远点
c++代码如下:
#include<bits/stdc++.h>
#define eps 1e-9
#define rep(i,x,y) for(register int i = x; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x; i >= y; -- i)
using namespace std;
const int N = 2005;
int n,cnt,s[N];
double ans ;
struct Point {
double x,y;
Point operator - (const Point b) const { return (Point){x - b.x,y - b.y}; }
double operator * (const Point b) { return x * b.y - y * b.x; }
}p[N];
const bool cmp(Point a,Point b) { return a.x < b.x||a.x == b.x&&a.y < b.y; }
int main()
{
scanf("%d",&n);
rep(i,1,n)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p + 1,p + 1 + n,cmp);
rep(i,1,n)
{
while(cnt > 1 && ((p[s[cnt]] - p[s[cnt - 1]])*(p[i] - p[s[cnt]])) < eps) cnt--;
s[++cnt] = i;
}
int lst = cnt;
repd(i,n - 1,1)
{
while(cnt > lst && ((p[s[cnt]] - p[s[cnt - 1]])*(p[i] - p[s[cnt]])) < eps) cnt--;
s[++cnt] = i;
}
cnt--;
rep(i,1,cnt)
{
int x = i%cnt + 1,y = (i + 2)%cnt + 1;
rep(j,i + 2,cnt)
{
while(x % cnt + 1 != j && fabs((p[s[x]] - p[s[i]]) * (p[s[x]] - p[s[j]])) < fabs((p[s[x + 1]] - p[s[i]]) * (p[s[x + 1]] - p[s[j]])))
x = x % cnt + 1;
while(y % cnt + 1 != i && fabs((p[s[y]] - p[s[i]]) * (p[s[y]] - p[s[j]])) < fabs((p[s[y + 1]] - p[s[i]]) * (p[s[y + 1]] - p[s[j]])))
y = y % cnt + 1;
ans = max(ans,fabs((p[s[x]] - p[s[i]])*(p[s[x]] - p[s[j]]))+fabs((p[s[y]] - p[s[i]])*(p[s[y]] - p[s[j]])));
}
}
printf("%.3lf",ans/2);
return 0;
}