zoukankan      html  css  js  c++  java
  • [HDU]2202最大三角形、3934Summer holiday

    http://acm.hdu.edu.cn/showproblem.php?pid=2202

    http://acm.hdu.edu.cn/showproblem.php?pid=3934

    在n个点中找出3个点,使得面积最大。

    这题用到的就是葛立恒扫描法。

    葛立恒扫描法是什么呢?现将现有的所有点进行排序,y从小到大。x从小到大。

    这样的话,我们可以得到什么呢?首先,y最小,x最小的一定是凸包点,这一点没有疑义吧。同理,x最大,y最大的也肯定是凸包点,我们所采用的步进法也将以这两个点作为开始。

    步进法分为两部分,我们姑且叫第一部分为左链,第二部分为右链。

    我们从左链开始,首先,取出0,1,2点。(至少需要3点才能比较,0是最小的点,上述已证明肯定是凸包点),假如0→2,斜率大于0→1,所以1肯定不是凸包点,舍去,接着0,2,3假如0→3,斜率大于0→2,那2也肯定不是凸包点,舍去。接下来重复此步骤。直至点n。(ps:上述斜率的比较用叉乘来进行,即叉乘结果为正的话,向左转,从而证明斜率大小)假如中间出现了y轴相等,x轴不等的点,这点暂时存入。(因为假设这个点最外围的,那这条线段的两个点都是凸包点。)如果接下来有斜率比这两条大的线的话,很明显,这两个点也要舍去。

    这样就判断完了左链,右链同理,不过起始点是从最大点开始。

    #include"stdio.h"
    #include"stdlib.h"
    #include"math.h"
    struct Point
    {
        int x;
        int y;
    };
    Point p[100010];
    int n;
    int cmp(const void *a,const void *b)     //判断快排时,摆放的位置,即x,y从小到大, 
    {
        Point *c =(Point *)a;
        Point *d =(Point *)b;
        if(c->y==d->y)
            return c->x-d->x;
        else
            return c->y-d->y;
    }
    int cross(Point p1,Point p2,Point p3)         //叉乘 
    {
        return (p3.x-p2.x)*(p1.y-p2.y)-(p3.y-p2.y)*(p1.x-p2.x);
    }
    int convex(int s[])
    {
        int i,m,m1; 
        for(m=0,i=0;i<n;i++){           //左链 
            while(m>1 && cross(p[s[m-2]],p[s[m-1]],p[i])>=0)
                m--;
            s[m++]=i;
        }
        m1=m;
        for(i=n-2;i>0;i--){             //右链 
            while(m>m1 && cross(p[s[m-2]],p[s[m-1]],p[i])>=0)
                m--;
            s[m++]=i;
        }
        return m;
    }
    double area(int i,int j,int k)
    {
        double s=fabs(double(p[i].x*p[j].y+p[j].x*p[k].y+p[k].x*p[i].y-p[i].y*p[j].x-p[j].y*p[k].x-p[k].y*p[i].x)/2);    
        return s;
    }
    int main()
    {
        int s[100010];
        double max,temp;
        int i,j,k,m;
        while(scanf("%d",&n)!=EOF)
        {
            
            for(i=0;i<n;i++)
                scanf("%d%d",&p[i].x,&p[i].y);
            qsort(p,n,sizeof(p[0]),cmp);
            m=convex(s);
            max=0;
            for(i=0;i<m-2;i++)
             for(j=i+1;j<m-1;j++)
              for(k=j+1;k<m;k++)
               {
                  temp=area(s[i],s[j],s[k]);
                  max=max>temp?max:temp;
               }
            printf("%.2lf
    ",max);
        }
        return 0;
    }
  • 相关阅读:
    最短路计数
    轻拍牛头(类埃式筛)
    子序列(尺取模板题)
    状压dp(洛谷:互不侵犯)
    刷题-力扣-73. 矩阵置零
    刷题-力扣-150. 逆波兰表达式求值
    刷题-力扣-300. 最长递增子序列
    刷题-力扣-1576. 替换所有的问号
    刷题-力扣-54. 螺旋矩阵
    刷题-力扣-705. 设计哈希集合
  • 原文地址:https://www.cnblogs.com/sjy123/p/3277917.html
Copyright © 2011-2022 走看看