求凸包后在凸包上旋转卡壳。然而复杂度要求较低，故可直接枚举四边形的一条对角线，另两个顶点在凸包上随这条对角线的移动具有单调性，所以总复杂度O(n2)。

 1 #include <bits/stdc++.h>
2 #define range(i,c,o) for(register int i=(c);i<(o);++i)
3 #define dange(i,c,o) for(register int i=(c);i>(o);--i)
4 using namespace std;
5
6 static const double eps=1e-7;
7
8 typedef pair<double,double> POINT;
9 #define x first
10 #define y second
11
12 inline POINT operator+(const POINT&P,const POINT&Q)
13 {
14     return make_pair(P.x+Q.x,P.y+Q.y);
15 }
16
17 inline POINT operator-(const POINT&P,const POINT&Q)
18 {
19     return make_pair(P.x-Q.x,P.y-Q.y);
20 }
21
22 inline double dis(const POINT&P,const POINT&Q)
23 {
24     return sqrt(pow(P.x-Q.x,2)+pow(P.y-Q.y,2));
25 }
26
27 inline double cross(const POINT&P,const POINT&Q)
28 {
29     return P.x*Q.y-P.y*Q.x;
30 }
31
32 inline double area(
33     const POINT&O,const POINT&P,const POINT&Q
34 )
35 {
36     return 0.5*cross(P-O,Q-O);
37 }
38
39 // 1 stand for LEFT and -1 stand for RIGHT
40 inline int turn(
41     const POINT&O,const POINT&P,const POINT&Q
42 )
43 {
44     double duct=area(O,P,Q);
45     return fabs(duct)<eps?0:(duct>0?1:-1);
46 }
47
48 POINT P[2005];
49 inline bool cmp(const POINT&A,const POINT&B)
50 {
51     int dir=turn(P[0],A,B);
52     return dir?dir>0:dis(P[0],A)>dis(P[0],B);
53 }
54
55 static int N,cnt=2;
56
57 inline int next(const int&x) {return x+1==cnt?0:x+1;}
58 inline int&move(int&x) {return ++x==cnt?x=0:x;}
59
60 int main()
61 {
62     scanf("%d",&N);
63     range(i,0,N) scanf("%lf%lf",&P[i].x,&P[i].y);
64     range(i,0,N)
65     {
66         if(P[i].y==P[0].y?P[i].x<P[0].x:P[i].y<P[0].y)
67         {
68             swap(P[i],P[0]);
69         }
70     }
71     sort(P+1,P+N,cmp);
72     range(i,2,N)
73     {
74         for(;cnt>1&&turn(P[cnt-2],P[cnt-1],P[i])<0;--cnt);
75         P[cnt++]=P[i];
76     }
77     double ans=0;
78     range(i,0,cnt)
79     {
80         int L=next(i),j=next(L),R=next(j);
81         for(;next(j)!=i;move(j))
82         {
83             for(;next(L)!=j&&
84                 area(P[i],P[next(L)],P[j])+eps>
85                 area(P[i],P[   L   ],P[j]);move(L)
86             );
87             for(j==R?move(R):0
88                 ;next(R)!=i&&
89                 area(P[j],P[next(R)],P[i])+eps>
90                 area(P[j],P[   R   ],P[i]);move(R)
91             );
92             ans=max(ans,area(P[i],P[L],P[j])+area(P[j],P[R],P[i]));
93         }
94     }
95     return printf("%.3lf\n",ans),0;
96 }
View Code