zoukankan      html  css  js  c++  java
  • 凸包---HDU 2202

    题意:给N个点,求着N个点中选择三个联的最大的三角形面积!

    注意精度:不然OJ上面会超时的

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    const double eps = 1e-8;
    using namespace std;
    struct point
    {
        int x,y;
    } p[50005],res[50005];
    int cross(point p0, point p1, point p2)//计算叉积
    {
        return(p1.x- p0.x) * (p2.y- p0.y) - (p1.y- p0.y) * (p2.x- p0.x);
    }//顺时针扫描,判断大于0(方向改变)的加入凸包,然后回溯
    double  dist(point a,point b)//两点距离
    {
        return sqrt((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    bool cmp(point  a, point  b)//按照y小到大排序,y相等按照x小到大排序
    {
        return(a.y< b.y|| (a.y== b.y&& a.x< b.x));
    }
    int Graham(int n)//求凸包,返回凸包上顶点的个数
    {
        int len, top=1;
        sort(p, p+ n, cmp);
        res[0] = p[0];
        res[1] = p[1];
        for(int i=2; i< n; i++)
        {
            while(top&& cross(res[top], res[top-1], p[i])<=eps)top--;
            res[++ top] = p[i];
        }
        len= top;
        res[++ top] = p[n-2];
        for(int i= n-3; i>=0; i--)
        {
            while(top!= len&& cross(res[top], res[top-1], p[i])<=eps)top--;//注意精度问题,不然会超时的
            res[++ top] = p[i];
        }
        return top;
    }
    int main()
    {
        int n,top;
        while(scanf("%d",&n)!=EOF)
        {
            double MAX=-1;
            for(int i=0; i<n; i++)
                scanf("%d%d", &p[i].x ,&p[i].y);
            top=Graham(n);
            for(int i=0; i<top-2; i++)
                for(int j=i+1; j<top-1; j++)
                    for(int k=j+1; k<top; k++)
                    {
                          double ss=fabs(cross(res[i],res[j],res[k]));
                          if(ss>MAX) MAX=ss;//暴力利用叉积计算三角形的面积
                    }
            printf("%.2f
    ",MAX/2.0);
        }
        return 0;
    }
    

    另一个版本的凸包

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    const double eps = 1e-8;
    using namespace std;
    struct point
    {
        int x,y;
    } p[50005],res[50005];
    int cross(point p0, point p1, point p2)//计算叉积
    {
        return(p1.x- p0.x) * (p2.y- p0.y) - (p1.y- p0.y) * (p2.x- p0.x);
    }//顺时针扫描,判断大于0(方向改变)的加入凸包,然后回溯
    double  dist(point a,point b)//两点距离
    {
        return sqrt((double)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    bool cmp(point  a, point  b)//极角排序,先用arctan()判断角大小,角度由小到大,然后用距离小到大排序
    {
         double t1 = atan2(a.y - p[0].y, a.x - p[0].x);
         double t2 = atan2(b.y - p[0].y, b.x - p[0].x);
         return t1>t2||(t1==t2&&dist(p[0],a)<dist(p[0],b));
    }
    int Graham(int n)//求凸包,返回凸包上顶点的个数
    {
        int len, top,tmp=0;
        for(int i=1;i<n;i++)
            if(p[tmp].y>p[i].y||(p[tmp].y==p[i].y&&p[tmp].x>p[i].x))
                tmp=i;
        swap(p[0],p[tmp]);//找出最左下角的点
        sort(p+1, p+ n,cmp);
        res[0] = p[0];
        res[1] = p[1];
        res[2] =p[2];
        top=2;
        for(int i=2; i<n; i++)
        {
            while(top>=2&& cross(res[top], res[top-1], p[i])<=eps)top--;
            res[++ top] = p[i];
        }//只用一次扫描
        res[++top]=p[n-1];//完了要把最后一个点加上去
        return top;
    }
    int main()
    {
        int n,top;
        while(scanf("%d",&n)!=EOF)
        {
            double MAX=-1;
            for(int i=0; i<n; i++)
                scanf("%d%d", &p[i].x ,&p[i].y);
            top=Graham(n);
            for(int i=0; i<top-2; i++)
                for(int j=i+1; j<top-1; j++)
                    for(int k=j+1; k<top; k++)
                    {
                          double ss=fabs(cross(res[i],res[j],res[k]));
                          if(ss>MAX) MAX=ss;//暴力利用叉积计算三角形的面积
                    }
            printf("%.2f
    ",MAX/2.0);
        }
        return 0;
    }
    
    


  • 相关阅读:
    POJ 2828 Buy Tickets (线段树 单点更新 变形)
    HDU 1754 I Hate It (线段树 单点更新)
    HDU 1166 敌兵布阵 (线段树 单点更新)
    sdut 2934 人活着系列之平方数 (完全背包变形)
    Codeforces Round #259 (Div. 2) C
    poj 1724 ROADS (bfs+优先队列)
    hdu 4901 The Romantic Hero (dp)
    MemSQL Start[c]UP 2.0
    BestCoder Round #2 1001 (简单处理)
    tc 2014 college tour 250 500
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3285637.html
Copyright © 2011-2022 走看看