这大概才是真正的第一题计算几何了。。首先这四个点肯定在凸包上,所以求出凸包,之后枚举四边形的对角线AB,凸包求出来之后点是按逆时针排序的,不妨设B在A的逆时针方向,那么就在A逆时针转到B的点之间取一个C点使三角形ABC面积最大,这个用叉积很方便,再在B逆时针转到A的点之间曲一个D使三角形ABD面积最大,现在ABCD就是以AB为对角线面积的最大值。。
当A固定B逆时针转的时候C,D都是逆时针转的,所以这有点像旋转卡壳,每一个点只需要O(N)就可以枚举完答案,所以总复杂度是O(N^2)。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#define ll long long
#define N 2005
#define t1 st[top]
#define t2 st[top-1]
using namespace std;
struct point{
double x,y;
point(){}
point(double x,double y):x(x),y(y){}
} a[N],st[N];
int top,end,i,n;
point operator-(point a,point b){return point(a.x-b.x,a.y-b.y);}
double operator*(point a,point b){return a.x*b.y-a.y*b.x;}
bool cmp(point a,point b)
{
if (a.x!=b.x) return a.x<b.x;else return a.y<b.y;
}
void push(point x)
{
while (top>=end+2&&(t1-t2)*(x-t1)<=0) top--;
st[++top]=x;
}
void graham()
{
end=0;top=0;
sort(a+1,a+1+n,cmp);
for (int i=1;i<=n;i++) push(a[i]);
end=top-1;
for (int i=n-1;i;i--) push(a[i]);
top--;
}
int next(int i){return i%top+1;}
double sRC()
{
double ans=0;
int l,r;
for (int i=1;i<=top;i++)
{
l=next(i);r=next(i+2);
for (int j=i+2;j<=top;j++)
{
if (r==j)r=next(r);
while (next(l)!=j&&(st[l]-st[i])*(st[j]-st[i])<(st[next(l)]-st[i])*(st[j]-st[i])) l=next(l);
while (next(r)!=i&&(st[j]-st[i])*(st[r]-st[i])<(st[j]-st[i])*(st[next(r)]-st[i])) r=next(r);
ans=max(ans,(st[l]-st[i])*(st[j]-st[i])+(st[j]-st[i])*(st[r]-st[i]));
}
}
return ans;
}
int main()
{
freopen("1069.in","r",stdin);
scanf("%d",&n);
for (i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
graham();
printf("%.3lf\n",sRC()/2);
}