• POJ 2187 Beauty Contest | 旋转卡壳


    题目:

    给n个点,输出距离最远的一对点的距离的平方


    题解:

    旋转卡壳模板!

    首先可以肯定的是最远的点一定是凸包的一对顶点!(这个正确性是很显然的)

    所以我们枚举每个顶点所在的边,将它平移,平移到经过的最远一个点就是含有这个点的最远距离

    所以N2是可以解决的!

    但是这个和枚举点是没区别的.

    但是如果我们逆时针枚举边的话,最远点变化也是逆时针的,所以接着上次的算就好啦.这样就优化到O(n)

    具体实现的话可以叉积用面积算

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 50005
    using namespace std;
    int n,m;
    void chkmax(int &a,const int &b)
    {
        if (a<b) a=b;
    }
    struct point
    {
        int x,y;
        point () {};
        point (int _x,int _y)
    	{
    	    x=_x,y=_y;
    	}
        point operator - (const point &a) const
    	{
    	    return point(x-a.x,y-a.y);
    	}
        int operator * (const point &a)const
    	{
    	    return x*a.y-y*a.x;
    	}
        int norm() const
    	{
    	    return x*x+y*y;
    	}
    }p[N],q[N];
    bool cmp(int u,int v)
    {
        int det=(p[u]-p[1])*(p[v]-p[1]);
        if (det!=0) return det>0;
        return (p[u]-p[1]).norm()<(p[v]-p[1]).norm();
    }
    void Graham()
    {
        int id=1;
        for (int i=2;i<=n;i++)
    	if (p[i].x<p[id].x || (p[i].x==p[id].x && p[i].y<p[id].y))
    	    id=i;
        if (id!=1) swap(p[1],p[id]);
        int per[N];
        for (int i=1;i<=n;i++) per[i]=i;
        sort(per+2,per+1+n,cmp);
        q[++m]=p[1];
        for (int i=2;i<=n;i++)
        {
    	int j=per[i];
    	while (m>=2 && (p[j]-q[m-1])*(q[m]-q[m-1])>=0)
    	    m--;
    	q[++m]=p[j];
        }
    }
    
    int Area(const point &x,const point &y,const point &z)
    {
        return (y-x)*(z-x);
    }
    int nxt(int x)
    {
        return x==m?1:x+1;
    }
    int solve()
    {
        if (m==2) return (q[2]-q[1]).norm();
        int res=0;
        q[m+1]=q[1];
        for (int i=1,j=3;i<=m;i++)
        {
    	while (nxt(j)!=i && Area(q[i],q[i+1],q[j])<=Area(q[i],q[i+1],q[j+1]))
    	    j=nxt(j);
    	chkmax(res,(q[j]-q[i]).norm());
    	chkmax(res,(q[j]-q[i+1]).norm());
        }
        return res;
    }
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
    	scanf("%d%d",&p[i].x,&p[i].y);
        Graham();
        printf("%d
    ",solve());
        return 0;
    }
    

     

  • 相关阅读:
    泛型与非泛型
    C# 调用CMD,执行DOS命令
    数据库设计随笔(ZZ)
    关于三层开发(zz)
    三层架构学习(转)
    Node.js & child_process All In One
    HTML5 Canvas Tag Cloud All In One
    macOS & VSCode terminal show current git branch All In One
    飞书 excel 固定列 All In One
    git diff one of committed file All In One
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8032581.html
Copyright © 2020-2023  润新知