• 凸包---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;
    }
    
    


  • 相关阅读:
    js中删除数组元素的几种方法
    js中的prototype
    分布式服务框架 Zookeeper -- 管理分布式环境中的数据
    angularjs事件传递$on、$emit和$broadcast
    cron表达式
    angularjs中的时间格式化过滤
    angularjs中的$q
    IOS 错误
    Swift 错误
    IOS 控件
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3285637.html
Copyright © 2020-2023  润新知