首页 > 其他 > 详细

poj 2079 Triangle,旋转卡壳求点集的最大三角形

时间:2014-08-20 09:20:56      阅读:282      评论:0      收藏:0      [点我收藏+]

给出一个点集,求顶点在点集中的最大的三角形面积。


我们知道这三角形的三个点肯定在凸包上,我们求出凸包之后不能枚举,因为题目n比较大,枚举的话要O(n^3)的数量级,所以采用旋转卡壳的做法:
首先枚举三角形的第一个顶点i, 初始化第二个顶点j=i+1和第三个顶点k=j+1,对k进行循环,直到找到第一个k使得cross(i,j,k)>cross(i,j,k+1),如果k==i进入下一次循环。
对j,k进行旋转,每次循环之前更新最大值,然后固定一个j,同样找到一个k使得cross(i,j,k)>cross(i,j,k+1)。对j进行++操作,继续进行下一次,知道j==k‘(对j,k旋转之前的(k+1)%n)或k==i为止。


double rotating_calipers(vector<Point>& points){
    vector<Point> p = ConvexHull(points);
    int n = p.size();
    p.push_back(p[0]);
    double ans = 0;
    for(int i=0; i<n; ++i)
    {
        int j = (i+1)%n;
        int k = (j+1)%n;
        //当Area(P[i], p[j], p[k+1]) <= Area(p[i], p[j], p[k]) 时停止旋转
        //即Cross(p[j]-p[i], p[k+1]-p[i]) - Cross(p[j]-p[i], p[k]-p[i]) <= 0
        //根据Cross(A,B) - Cross(A,C) = Cross(A,B-C)
        //化简得Cross(p[j]-p[i], p[k+1] - p[k]) <= 0
        while(k!=i && Cross(p[j]-p[i], p[k+1]-p[k]) > 0)
            k = (k+1) % n;
        if(k==i) continue;
        int kk = (k+1) % n;
        while(j!=kk && k!=i)
        {
            ans = max(ans, Cross(p[j]-p[i], p[k]-p[i]));
            while(k!=i && Cross(p[j]-p[i], p[k+1]-p[k]) > 0)
                k = (k+1) % n;
            j = (j+1) % n;
        }
    }
    return ans*0.5;
}


poj 2079 Triangle,旋转卡壳求点集的最大三角形,布布扣,bubuko.com

poj 2079 Triangle,旋转卡壳求点集的最大三角形

原文:http://blog.csdn.net/yew1eb/article/details/38701183

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!