题意:
给出n个二维坐标点,找出三个点,它们组成的三角形面积最大。
思路:
首先,面积最大的三角形的三个点一定在凸包上,我们先求所有点的凸包,然后选择一个边i、j,枚举k,找到一个最大的面积,然后定下i,枚举j和k,找到最大的面积。
pojG++是坑!
代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<string>
#define EPS 1e-10
#define MAXN 50100
using namespace std;
struct point
{
double x,y;
point(){}
point(double tx,double ty):x(tx),y(ty){}
point(const point &tt)
{
x=tt.x;
y=tt.y;
}
};
point data[MAXN];
point convex[MAXN];
point start(0,0);
inline double cross(const point &p1,const point &p2,const point &q1,const point &q2)
{
return (q2.y-q1.y)*(p2.x-p1.x)-(q2.x-q1.x)*(p2.y-p1.y);
}
inline bool cmp1(const point &a,const point &b)
{
if(a.y==b.y)
return a.x<b.x;
return a.y<b.y;
}
inline bool cmp2(const point &a,const point &b)//逆时针排序
{
point origin;
origin=start;
return cross(origin,a,origin,b)>0||(cross(origin,a,origin,b)==0&&fabs(a.x)<fabs(b.x));
}
inline void convex_hull(int &cnt,int n)
{
sort(data,data+n,cmp1);
start=data[0];
sort(data+1,data+n,cmp2);
convex[cnt++]=start;
convex[cnt++]=data[1];
for(int i=2;i<n;++i)
{
while(cnt>=2&&cross(convex[cnt-2],convex[cnt-1],convex[cnt-1],data[i])<=0)
--cnt;
convex[cnt++]=data[i];
}
}
inline double rotating_calipers(int n)
{
int j=1,k=0;
double area=0;
for(int i=0;i<n;++i)
{
j=(i+1)%n;
k=(j+1)%n;
while(fabs(cross(convex[i],convex[j],convex[i],convex[k]))<
fabs(cross(convex[i],convex[j],convex[i],convex[(k+1)%n])))
k=(k+1)%n;
while(j!=i&&k!=i)
{
area=max(area,fabs(cross(convex[i],convex[j],convex[i],convex[k])));
while(fabs(cross(convex[i],convex[j],convex[i],convex[k]))<
fabs(cross(convex[i],convex[j],convex[i],convex[(k+1)%n])))
k=(k+1)%n;
j=(j+1)%n;
}
}
return area;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
if(n==-1)
break;
for(int i=0;i<n;i++)
scanf("%lf%lf",&data[i].x,&data[i].y);
if(n<=2)
{
printf("0.00\n");
continue;
}
int cnt=0;
convex_hull(cnt,n);
if(cnt<=2)
printf("0.00\n");
else
{
if(cnt==3)
printf("%.2lf\n",fabs(cross(convex[0],convex[1],convex[0],convex[2]))/2);
else
printf("%.2lf\n",rotating_calipers(cnt)/2);
}
}
return 0;
}