zoukankan      html  css  js  c++  java
  • 凸包

    Graham算法

    先找出以(y)值为第一关键字和以(x)值为第二关键字最小的点,以其作为基准点

    然后对剩下的点进行极角序排序

    向栈中加点,并维护凸性,最终栈中的点即为凸包上的点

    复杂度即为排序的复杂度(O(n log n))

    (code:)

    struct point
    {
    	double x,y;
    }p[maxn],st[maxn];
    point operator -(const point &a,const point &b)
    {
        return (point){a.x-b.x,a.y-b.y};
    }
    double operator *(const point &a,const point &b)
    {
        return a.x*b.y-a.y*b.x;
    }
    double dis(const point &a,const point &b)
    {
    	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    bool cmp1(const point &a,const point &b)
    {
        if(a.x==b.x) return a.y<b.y;
        return a.x<b.x;
    }
    bool cmp2(const point &a,const point &b)
    {
    	if((a-p[1])*(b-p[1])==0) return dis(a,p[1])<dis(b,p[1]);
    	return (b-a)*(p[1]-a)>0;
    }
    void graham()
    {
    	sort(p+1,p+n+1,cmp1);
    	sort(p+2,p+n+1,cmp2);
    	st[1]=p[1],top=1;
    	for(int i=2;i<=n;++i)
    	{
    		while(top>1&&(st[top-1]-p[i])*(st[top]-p[i])<=0) top--;
    		st[++top]=p[i];
    	}
    }
    

    旋转卡壳

    对踵点,如果过凸多边形上两点作一对平行线,使得整个多边形都在这两条线之间,那么这两个点被称为一对对踵点,直径一定会在对踵点中产生

    逆时针枚举边,然后从上次枚举到对踵点的继续逆时针向后枚举来求解

    实现时用双指针法来保证(O(n))的复杂度,用叉积求面积来判断点到边的距离

    (code:)

    struct point
    {
    	int x,y;
    }p[maxn],st[maxn];
    point operator -(const point &a,const point &b)
    {
        return (point){a.x-b.x,a.y-b.y};
    }
    double operator *(const point &a,const point &b)
    {
        return a.x*b.y-a.y*b.x;
    }
    int dis(const point &a,const point &b)
    {
    	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
    }
    bool cmp1(const point &a,const point &b)
    {
        if(a.x==b.x) return a.y<b.y;
        return a.x<b.x;
    }
    bool cmp2(const point &a,const point &b)
    {
    	if((a-p[1])*(b-p[1])==0) return dis(a,p[1])<dis(b,p[1]);
    	return (b-a)*(p[1]-a)>0;
    }
    void graham()
    {
    	sort(p+1,p+n+1,cmp1);
    	sort(p+2,p+n+1,cmp2);
    	st[1]=p[1],top=1;
    	for(int i=2;i<=n;++i)
    	{
    		while(top>1&&(st[top-1]-p[i])*(st[top]-p[i])<=0) top--;
    		st[++top]=p[i];
    	}
    }
    void get()
    {
    	int j=1;
    	st[top+1]=st[1];
    	for(int i=1;i<=top;++i)
    	{
    		while((st[i+1]-st[i])*(st[j]-st[i])<(st[i+1]-st[i])*(st[j+1]-st[i])) j=(j+1)%top;
    		ans=max(ans,max(dis(st[i],st[j]),dis(st[i+1],st[j])));
    	}
    }
    
  • 相关阅读:
    ASP.NET Zero--10.一个例子(3)商品分类管理-新建
    ASP.NET Zero--9.一个例子(2)商品分类管理-列表
    ASP.NET Zero--8.一个例子(1)菜单添加
    ASP.NET Zero--7.控制器加权限
    ASP.NET Zero--6.菜单加权限
    ASP.NET Zero--5.配置权限
    ASP.NET Zero--4.不使用谷歌字体,提升加载速度
    ASP.NET Zero--2.如何启动
    C# mongoDB Driver 使用对象方式最完善查询语法大全
    ef 数据库连接字符串加密
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229583.html
Copyright © 2011-2022 走看看