构造凸包,枚举对角线,旋转卡壳计算面积
//bzoj 最大土地面积
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define eps 1e-8
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=2005;
struct point {double x,y;} p[mxn],s[mxn];
int n,top;
inline double dis(point a,point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
inline double cross(point p0,point p1,point p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
inline bool comp(point a,point b)
{
double tmp=cross(p[0],a,b);
if(tmp>0 || (fabs(tmp)<=eps && dis(p[0],a)>dis(p[0],b))) return 1;
return 0;
}
inline void graham()
{
int i,j; //注意s[0]也是栈中元素
s[0]=p[0],s[1]=p[1],top=1;
fo(i,2,n-1)
{
while(top && cross(s[top-1],s[top],p[i])<=0) top--;
s[++top]=p[i];
}
top++;
}
inline void rc()
{
int i,j,q=1;
double ans=0;
fo(i,0,top-1)
{
int a=(i+1)%top,b=(i+3)%top;
fo(j,i+2,top-1)
{
while(fabs(cross(s[(a+1)%top],s[i],s[j]))>=fabs(cross(s[a],s[i],s[j])))
a=(a+1)%top;
while(fabs(cross(s[(b+1)%top],s[i],s[j]))>=fabs(cross(s[b],s[i],s[j])))
b=(b+1)%top;
ans=max(ans,fabs(cross(s[a],s[i],s[j]))+fabs(cross(s[b],s[i],s[j])));
}
}
printf("%.3lf\n",ans/2);
}
int main()
{
int i,j,u,v;
scanf("%d",&n);
fo(i,0,n-1) scanf("%lf%lf",&p[i].x,&p[i].y);
u=0;
fo(i,0,n-1)
if(p[u].y>p[i].y || ((p[u].y-p[i].y)<=eps && p[u].x>p[i].x))
u=i;
swap(p[0],p[u]);
sort(p+1,p+n,comp);
graham();
rc();
return 0;
}