求出凸包,枚举一下对角线,然后就可以用神奇的旋转卡壳了(其实感觉旋转卡壳就是用凸包的性质给暴力加了一点小优化)
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 using namespace std; 5 int n,top; 6 double ans; 7 struct point{double x,y;}p[2005],s[2005]; 8 double dis(point a, point b) 9 { 10 return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); 11 } 12 point operator - (point a, point b) 13 { 14 point t; t.x=a.x-b.x; t.y=a.y-b.y; return t; 15 } 16 double operator * (point a, point b) 17 { 18 return a.x*b.y-a.y*b.x; 19 } 20 bool operator < (point a, point b) 21 { 22 if ((a-p[1])*(b-p[1])==0) return dis(a,p[1])<dis(b,p[1]); 23 return (a-p[1])*(b-p[1])>0; 24 } 25 void Graham() 26 { 27 int k=1; 28 for (int i=2; i<=n; i++) 29 if (p[k].y>p[i].y || (p[k].y==p[i].y && p[k].x>p[i].x)) k=i; 30 swap(p[1],p[k]); sort(p+2,p+n+1); 31 s[++top]=p[1]; s[++top]=p[2]; 32 for (int i=3; i<=n; i++) 33 { 34 while (top>1 && (s[top]-p[i])*(s[top-1]-p[i])>=0) top--; 35 s[++top]=p[i]; 36 } 37 } 38 void RC() 39 { 40 s[top+1]=p[1]; 41 int a,b; 42 for (int x=1; x<=top; x++) 43 { 44 a=x%top+1; b=(x+2)%top+1; 45 for (int y=x+2; y<=top; y++) 46 { 47 while (a%top+1!=y && (s[y]-s[x])*(s[a+1]-s[x])<(s[y]-s[x])*(s[a]-s[x])) a=a%top+1; 48 while (b%top+1!=x && (s[b+1]-s[x])*(s[y]-s[x])<(s[b]-s[x])*(s[y]-s[x])) b=b%top+1; 49 ans=max(ans,-((s[y]-s[x])*(s[a]-s[x])+(s[b]-s[x])*(s[y]-s[x]))); 50 } 51 } 52 } 53 int main() 54 { 55 scanf("%d",&n); 56 for (int i=1; i<=n; i++) scanf("%lf%lf",&p[i].x,&p[i].y); 57 Graham(); RC(); 58 printf("%.3lf",ans/2); 59 return 0; 60 }