由于最大三角形总会由凸包的顶点围成,故要先找到一个凸包,然后枚举凸包的顶点
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define maxn 50005 const double pi=acos(-1.0); struct Point{ int x,y; }s[maxn]; int st[maxn],top; int cross(Point p0,Point p1,Point p2) { return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } double dist(Point p1,Point p2) { int tmp=(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y); return sqrt(tmp); } bool cmp(Point p1,Point p2) //极角排序 { int tmp=cross(s[0],p1,p2); if(tmp>0) return true; else if(tmp==0&&dist(s[0],p1)<dist(s[0],p2)) return true; else return false; } void Graham(int n) { if(n==1) { top=0; st[0]=0;} if(n==2) { top=1; st[0]=0;st[1]=1;} if(n>2) { int i; st[0]=0,st[1]=1; top=1; for(i=2;i<n;i++) { while(top>0&&cross(s[st[top-1]],s[st[top]],s[i])<0) top--; st[++top]=i; } } top++; //记录凸包上的点的总个数 } int main() { int n; while(scanf("%d",&n)!=EOF){ scanf("%d%d",&s[0].x,&s[0].y); Point p0; p0.x=s[0].x,p0.y=s[0].y; int k=0; for(int i=1;i<n;i++) { scanf("%d%d",&s[i].x,&s[i].y); if((p0.y>s[i].y)||(p0.y==s[i].y&&p0.x>s[i].x)) { p0.x=s[i].x; p0.y=s[i].y; k=i; } } s[k]=s[0]; s[0]=p0; sort(s+1,s+n,cmp); Graham(n); double ans=0; for(int i=0;i<top;i++) for(int j=i+1;j<top;j++) for(int k=j+1;k<top;k++) { ans=max(ans,1.0*cross(s[st[k]],s[st[i]],s[st[j]])); } printf("%.2f\n",ans*0.5); } return 0; }