• 凸包


    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])));
    	}
    }
    
  • 相关阅读:
    JavaScript或jQuery模拟点击超链接和按钮
    web开发中目录路径问题的解决
    jQuery操作复选框的简单使用
    php中常用魔术方法的举例
    Code-Validator:验证经度、验证维度
    Code-Validator:验证身份证号
    Code-Validator:验证IPv6地址
    Code-Validator:验证IPv4地址
    Code-Validator:验证网址(可以匹配IPv4地址但没对IPv4地址进行格式验证;IPv6暂时没做匹配)
    Code-Validator:验证电子邮箱
  • 原文地址:https://www.cnblogs.com/lhm-/p/12229583.html
Copyright © 2020-2023  润新知