原题
给出n个点,求最大面积三角形。
最大面积三角形一定在凸包上,所以先Graham求凸包。在凸包上旋转卡壳(固定一个定点,旋转一个,在旋转另一个)。
O(n^2)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100010
#define eps 1e-8
using namespace std;
int n,m,top,per[N];
double x,y,area;
struct point
{
double x,y;
point() : x(0),y(0) {}
point(double _x,double _y) : x(_x),y(_y) {}
bool operator < (const point &b) const
{
return x<b.x || (x==b.x && y<b.y);
}
point operator + (const point &b) const
{
return point(x+b.x,y+b.y);
}
point operator - (const point &b) const
{
return point(x-b.x,y-b.y);
}
point operator * (const double &b) const
{
return point(x*b,y*b);
}
double operator * (const point &b) const
{
return x*b.y-b.x*y;
}
double norm()
{
return x*x+y*y;
}
}p[N],q[N];
double ABS(double x) { return x>=0?x:-x; }
int dcmp(double x)
{
if (x<=eps && x>=-eps) return 0;
return x>0?1:-1;
}
bool cmp(int i,int j)
{
int d=(p[i]-p[1])*(p[j]-p[1]);
if (d!=0) return d<0;
return (p[i]-p[1]).norm()>(p[j]-p[1]).norm();
}
void Graham()
{
sort(p+1,p+n+1);
top=0;
for (int i=1;i<=n;i++)
{
while (top>1 && dcmp((q[top]-q[top-1])*(p[i]-q[top-1]))<=0)
--top;
q[++top]=p[i];
}
int k=top;
for (int i=n-1;i>=1;i--)
{
while (top>k && dcmp((q[top]-q[top-1])*(p[i]-q[top-1]))<=0)
--top;
q[++top]=p[i];
}
if (n>1) --top;
}
double rotating()
{
if (top<=2) return 0;
if (top==3) return ABS(((q[2]-q[1])*(q[3]-q[1]))/2.0);
double ans=0;
for (int i=1;i<=top;i++)
{
int j=i%top+1;
int k=j%top+1;
while (dcmp(ABS((q[i]-q[j])*(q[i]-q[k]))-ABS((q[i]-q[j])*(q[i]-q[k%top+1])))<0)
k=k%top+1;
while (i!=j && j!=k && i!=k)
{
ans=max(ans,ABS(((q[i]-q[j])*(q[i]-q[k]))/2.0));
while(dcmp(ABS((q[i]-q[j])*(q[i]-q[k]))-ABS((q[i]-q[j])*(q[i]-q[k%top+1])))<0)
k=k%top+1;
j=j%top+1;
}
}
return ans;
}
int main()
{
while (~scanf("%d",&n))
{
if (n==-1) break;
top=0;
for (int i=1;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
Graham();
area=rotating();
printf("%.2lf\n",area);
}
return 0;
}