Description
在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大。
Input
第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。
Output
最大的多边形面积,答案精确到小数点后3位。
Sample Input
0 0
1 0
1 1
0 1
0.5 0.5
Sample Output
HINT
数据范围 n<=2000, |x|,|y|<=100000
想摔键盘。。无论如何都像摔键盘。调了整整三个小时。最后随手把叉积算面积比较的>改成>=竟然就过了。。过了。。了【摔】
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这题我们先算出凸包。然后就好办了。枚举对角线上两个点。我们可以发现另外两个点是单调的。可以直接求出来。然后复杂度就是O(n^2)的了
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
刚刚又想了一下。。不加等号是不是会卡在某个点而不往后推进。。【雾】
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
struct points
{
double x,y;
}a[5001],chs[5001];
inline double max(double x,double y)
{
if(x>y)
return x;
return y;
}
inline double xabs(double x)
{
if(x<0)
x=-x;
return x;
}
inline double dis(points x,points y)
{
return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
}
inline double multi(points p0, points p1, points p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
inline bool cmp(points x,points y)
{
if(multi(x,y,a[1])>0)
return true;
if(multi(x,y,a[1])==0&&dis(x,a[1])<dis(y,a[1]))
return true;
return false;
}
int main()
{
// freopen("land.in","r",stdin);
// freopen("land.out","w",stdout);
int n;
scanf("%d",&n);
int i;
for(i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
double minx=2100000000,miny=2100000000;
int d=0;
for(i=1;i<=n;i++)
{
if(a[i].y<miny)
{
minx=a[i].x;
miny=a[i].y;
d=i;
}
else if(a[i].y==miny)
{
if(a[i].x<minx)
{
minx=a[i].x;
d=i;
}
}
}
points t;
t=a[d];
a[d]=a[1];
a[1]=t;
sort(a+2,a+1+n,cmp);
int sp=1,k=2;
chs[0]=a[n];
chs[1]=a[1];
while(k<=n)
{
double x=multi(chs[sp],chs[sp-1],a[k]);
if(x<=0)
{
sp++;
chs[sp]=a[k];
k++;
}
else
sp--;
}
//printf("%d\n",sp);
int p1,p2,p3;
double ans=0;
for(i=sp+1;i<=2*sp;i++)
chs[i]=chs[i-sp];
for(i=1;i<=sp;i++)
{
p1=i+2;
p2=i+1;
p3=p1+1;
while(p1-i!=sp)
{
while(p2+1!=p1&&xabs(multi(chs[i],chs[p1],chs[p2+1]))>=xabs(multi(chs[i],chs[p1],chs[p2])))
p2++;
while(p3+1-i<=sp&&xabs(multi(chs[i],chs[p1],chs[p3+1]))>=xabs(multi(chs[i],chs[p1],chs[p3])))
p3++;
ans=max(xabs(multi(chs[i],chs[p1],chs[p2]))+xabs(multi(chs[i],chs[p1],chs[p3])),ans);
// if(ans>900000000)
// ans=0;
p1=p1+1;
if(p3<=p1)
p3=p1+1;
}
}
printf("%.3lf\n",ans/double(2));
return 0;
}