旋转卡壳 POJ 2079 Triangle

来源:互联网 发布:倩女手游 mac 编辑:程序博客网 时间:2024/05/01 22:19
Triangle
Time Limit: 3000MS Memory Limit: 30000KTotal Submissions: 8008 Accepted: 2363

Description

Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices are from the given points.

Input

The input consists of several test cases. The first line of each test case contains an integer n, indicating the number of points on the plane. Each of the following n lines contains two integer xi and yi, indicating the ith points. The last line of the input is an integer −1, indicating the end of input, which should not be processed. You may assume that 1 <= n <= 50000 and −104 <= xi, yi <= 104 for all i = 1 . . . n.

Output

For each test case, print a line containing the maximum area, which contains two digits after the decimal point. You may assume that there is always an answer which is greater than zero.

Sample Input

33 42 62 752 63 92 08 06 5-1

Sample Output

0.5027.00

Source

Shanghai 2004 Preliminary

 

题意:给出一个点集,求出最大面积的三角形的面积。

 

思路:最大三角形的三个顶点一定在凸包上面。那么假设我们选了两个点,其实另外一点就已经确定了,就在离这条直线最远的定点。怎么找?用旋转卡壳的思想,我们假设前一个已经找到了对应的第三个点,那么我们将第二个点逆时针换一个,此时,原来第三个点的索引我们不需要变为从0开始重新找一遍,我们的第三个点只需要继续往逆时针方向走就行了,知道离直线最远,停下来,算一下面积,然后继续让第二个点走一个点,继续重复上面的操作,当走完一圈的时候,我们的第一个点逆时针走一个点,然后第二个点变为第一个点的下一个点,第三个点变为第二个点的下一个店。继续以上的操作就行了。 感觉复杂度应该是O(n^2)

 

 

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string.h>#include<algorithm>#include<cmath>using namespace std;const int maxn=50000+5;#define LL long longstruct Point{    LL x,y;    Point(LL x=0,LL y=0)    :x(x),y(y) { }    bool operator<(const Point&p) const    {        return x<p.x||(x==p.x&&y<p.y);    }    bool operator==(const Point&p) const    {        return x==p.x&&y==p.y;    }};typedef Point Vector;Vector operator+(const Vector&a,const Vector&b) { return Vector(a.x+b.x,a.y+b.y); }Vector operator-(const Vector&a,const Vector&b) { return Vector(a.x-b.x,a.y-b.y); }LL Dot(const Vector&a,const Vector&b) { return a.x*b.x+a.y*b.y; }LL Cross(const Vector&a,const Vector&b) { return a.x*b.y-a.y*b.x; }int Convexhull(Point *p,int n,Point *ch){    sort(p,p+n);    n=unique(p,p+n)-p;    int m=0;    for(int i=0;i<n;++i) {        while(m>1&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-1])<=0) --m;        ch[m++]=p[i];    }    int k = m;    for(int i=n-2;i>=0;--i) {        while(m>k&&Cross(ch[m-1]-ch[m-2],p[i]-ch[m-1])<=0) --m;        ch[m++]=p[i];    }    if(n>1) --m;    return m;}double RotateCalipers(Point*p,int n){    p[n]=p[0];    if(n<3) return 0;    int j,k;    double ret=0;    for(int i=0;i<n;++i) {        j=(i+1)%n,k=(i+2)%n;        for(;;) {            while(Cross(p[j]-p[i],p[k+1]-p[k])>0) k=(k+1)%n;            if(k==j || k==i) break;            double S=Cross(p[j]-p[i],p[k]-p[i]);            if(S>ret) ret=S;            j=(j+1)%n;        }    }    return ret/2;}Point p[maxn],hull[maxn];int n;void input(){    for(int i=0;i<n;++i) scanf("%I64d%I64d",&p[i].x,&p[i].y);}void solve(){    int m=Convexhull(p,n,hull);    double ans=RotateCalipers(hull,m);    printf("%.2lf\n",ans);}int main(){    while(scanf("%d",&n)==1)    {        if(n==-1) return 0;        input();        solve();    }    return 0;}


 

 

 

 

 

0 0