题目链接:http://poj.org/problem?id=2079
方法:凸包+旋转卡壳(O(n^2))
- #include<cstdio>
- #include<cmath>
- #include<algorithm>
- #define N 50000
- using namespace std;
- //定义点
- struct Point
- {
- double x, y;
- Point(double x = 0, double y = 0) : x(x), y(y) {}
- };
- typedef Point Vector;
- Point p[N+10];
- Point ch[N+10];
- const double eps = 1e-10;
- int dcmp(double x)
- {
- if(fabs(x) < eps) return 0;
- else return x < 0 ? -1 : 1;
- }
- //点-点=向量
- Vector operator - (Point A, Point B) {return Vector(A.x-B.x, A.y-B.y);}
- double Cross(Vector A, Vector B){return A.x*B.y - A.y*B.x;}
- bool cmp ( Point a, Point b )
- {
- if ( a.x != b.x ) return a.x < b.x;
- else return a.y < b.y;
- }
- int ConvexHull(Point ch[], int n, Point p[])
- {
- sort(p, p+n, cmp);
- int m = 0;
- //下凸边
- for(int i = 0; i < n; i++)
- {
- while(m > 1 && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;
- ch[m++] = p[i];
- }
- int k = m;
- //上凸边
- for(int i = n-2; i >= 0; i--)
- {
- while(m > k && dcmp(Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])) <= 0) m--;
- ch[m++] = p[i];
- }
- if(n > 1) m--;
- return m;
- }
- double rotaing_calipers(Point ch[], int n)
- {
- int p;
- int i, j;
- double ans = 0;
- for( i = 0; i < n-1; i++)
- {
- p = 1;
- for( j = i+1; j < n; j++)
- {
- while(fabs(Cross(ch[j]-ch[i],ch[p+1]-ch[i])) > fabs((Cross(ch[j]-ch[i],ch[p]-ch[i]))))
- p = (p+1) % (n-1);
- ans = max(ans, fabs(Cross(ch[i]-ch[p],ch[j]-ch[p])));
- }
- ans = max(ans, fabs(Cross(ch[i]-ch[p],ch[j]-ch[p])));
- }
- return ans/2;
- }
- int main ()
- {
- // freopen("a.txt","r", stdin);
- int n;
- while(scanf("%d", &n) != EOF)
- {
- if(n == -1) break;
- for(int i = 0; i < n; i++)
- scanf("%lf %lf", &p[i].x, &p[i].y);
- int len = ConvexHull(ch, n, p);
- double ans = rotaing_calipers(ch, len);
- printf("%.2f\n", ans);
- }
- return 0;
- }