• luogu P1452 [USACO03FALL]Beauty Contest G /【模板】旋转卡壳


    LINK:旋转卡壳

    如题 是一道模板题。

    容易想到n^2暴力 当然也能随机化选点 (还真有人过了

    考虑旋转卡壳 其实就是对于某个点来说找到其最远的点。

    在找的过程中需要借助一下个点的帮助 利用当前点到当前线段的所构成的面积来判断高度是否足够高。

    容易证明第二个指针最多跑两圈 第一个指针跑一圈 所以复杂度O(n).

    不过求凸包是nlogn的。

    值得一提的是 当高度相同时 此时最多会出现两个点 然而这两个点都有可能成为答案 所以都要更新.

    const int MAXN=50010;
    struct Vec
    {
    	db x,y;int id;Vec(){}Vec(db _x,db _y){x=_x;y=_y;}
    	inline Vec operator +(Vec b){return Vec(x+b.x,y+b.y);}
    	inline Vec operator -(Vec b){return Vec(x-b.x,y-b.y);}
    	inline Vec operator -(){return Vec(-x,-y);}
    	inline db operator *(Vec b){return x*b.x+y*b.y;}//点积
    	inline db operator %(Vec b){return x*b.y-b.x*y;}//叉积
    	inline db operator ~(){return x*x+y*y;}//模长的平方
    	inline bool operator ==(Vec b){return fabs(x-b.x)<=EPS&&fabs(y-b.y)<=EPS;}
    	inline bool operator !=(Vec b){return fabs(x-b.x)>EPS||fabs(y-b.y)>EPS;}
    	inline Vec Unit(){db _=sq(x*x+y*y);return Vec(x/_,y/_);}//单位化
    	inline Vec Norm(){db _=sq(x*x+y*y);return Vec(-y/_,x/_);}//单位法向量
    	inline bool Quad(){return y>EPS||(fabs(y)<=EPS&&x>=-EPS);}
    	inline bool operator <(Vec b){return fabs(y-b.y)<=EPS?x<b.x:y<b.y;}
    };typedef Vec pt;
    inline Vec operator /(Vec a,db k){return Vec(a.x/k,a.y/k);}
    inline Vec operator *(db k,Vec a){return Vec(a.x*k,a.y*k);}
    inline Vec operator *(Vec a,db k){return Vec(a.x*k,a.y*k);}
    inline bool para(Vec a,Vec b){return fabs(a%b)<=EPS;}//判断a b是否平行
    inline bool Toleft(Vec a,Vec b){return b%a>EPS;}//判断a是否在b的左边
    inline void O(pt a,char c=' '){printf("(%.3lf,%.3lf)%c",a.x,a.y,c);}
    int n,top,ans;
    pt a[MAXN],s[MAXN],LTL;
    int w1[MAXN],w2[MAXN];
    inline bool cmpltl(pt a,pt b){return para(a=a-LTL,b=b-LTL)?~a<~b:Toleft(b,a);}
    inline int dis(int x,int y){return pf(w1[x]-w1[y])+pf(w2[x]-w2[y]);}
    inline void RC()
    {
    	s[top+1]=s[1];
    	for(int i=1,j=2;i<=top;++i)
    	{
    		while((s[i+1]-s[i])%(s[j]-s[i])<(s[i+1]-s[i])%(s[j+1]-s[i]))j=j%top+1;
    		ans=max(ans,dis(s[i].id,s[j].id));ans=max(ans,dis(s[i].id,s[j+1].id));
    	}
    	return;
    }
    signed main()
    {
    	//freopen("1.in","r",stdin);
    	gt(n);
    	rep(1,n,i)
    	{
    		gt(w1[i]);gt(w2[i]);
    		a[i].x=w1[i];
    		a[i].y=w2[i];
    		a[i].id=i;
    	}
    	LTL=*min_element(a+1,a+1+n);
    	sort(a+1,a+1+n,cmpltl);
    	rep(1,n,i)
    	{
    		while(top>1&&!Toleft(a[i]-s[top-1],s[top]-s[top-1]))--top;
    		s[++top]=a[i];
    	}
    	RC();put(ans);
    	return 0;
    }
    
  • 相关阅读:
    F#周报2019年第33期
    The .NET World——gPRC概览
    编程杂谈——Non-breaking space
    F#周报2019年第32期
    F#周报2019年第31期
    F#周报2019年第30期
    pat 乙级 1015. 德才论 (25) c++
    pat 乙级 1008. 数组元素循环右移问题 (20)
    PAT 乙级 1007. 素数对猜想 (20) c++ 筛选法求素数
    PAT-B 1005. 继续(3n+1)猜想 (25) c++
  • 原文地址:https://www.cnblogs.com/chdy/p/12804424.html
Copyright © 2020-2023  润新知