zoukankan      html  css  js  c++  java
  • UVALive 4728 Squares (平面最远点对)

    题意:n个平行于坐标轴的正方形,求出最远点对的平方

    题解:首先求出凸包,可以证明最远点对一定是凸包上的点对,接着可以证明最远点对(每个点的对踵点)一定只有3*n/2对

    接着使用旋转卡壳找到最远点对,但是白书上的算法过于麻烦

    所以我看到一个简单想法就是:

    可以直接枚举每个点,接着枚举这个点对应最远的点(三角形面积最大)

    这儿对踵点满足一个单峰性质,所以可以使用类似双指针方式维护

    //n个平行于坐标轴的正方形,求出最远点对的平方
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define eps 1e-8
    #define sgn(x) (x<-eps? -1 : x<eps? 0:1)
    #define zero(x) (((x)>0?(x) : -(x))<eps)
    const int Max=5e5+7;
    struct Point
    {
        double x,y;
        Point(double x=0,double y=0):x(x),y(y) {}
        inline Point operator-(const Point& a)const
        {
            return Point(x-a.x,y-a.y);
        }
        inline bool operator<(const Point& a)const
        {
            return sgn(x-a.x)<0||zero(x-a.x)&&sgn(y-a.y)<0;
        }
        inline bool operator!=(const Point& a)const
        {
            return !(zero(x-a.x)&&zero(y-a.y));
        }
    };
    typedef Point Vector;
    double Cross(Vector A,Vector B)
    {
        return A.x*B.y-A.y*B.x;
    }
    double Dis(Point A,Point B)
    {
        return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    }
    int ConvexHull(Point* p,int n,Point* convex)
    {
        sort(p,p+n);
        int m=0,k=1;
        for(int i=0; i<n; ++i)
        {
            if(p[k-1]!=p[i])
            {
                p[k++]=p[i];
            }
        }
        n=k;
        for(int i=0; i<n; ++i)
        {
            while(m>1&&Cross(convex[m-1]-convex[m-2],p[i]-convex[m-2])<0)
                m--;
            convex[m++]=p[i];
        }
        k=m;
        for(int i=n-2; i>=0; --i)
        {
            while(m>k&&Cross(convex[m-1]-convex[m-2],p[i]-convex[m-2])<0)
                m--;
            convex[m++]=p[i];
        }
        if(n>1)
            m--;
        return m;
    }
    double RotateStuck(Point* convex,int n)//旋转卡壳(前提:一个凸包),注意凸包去重点不要三点共线
    {
        double ans=0;
        int q=1;
        convex[n]=convex[0];//避免取模
        for(int p=0; p<n; ++p)//枚举一条边
        {
            while(Cross(convex[p+1]-convex[p],convex[q+1]-convex[p])>//这儿用的是三角形面积的比较
                  Cross(convex[p+1]-convex[p],convex[q]-convex[p]))//找到对应p这条个点的最远点(由于单峰函数,所以结果类似双指针)
                q=(q+1)%n;
            ans=max(ans,max(Dis(convex[p],convex[q]),Dis(convex[p+1],convex[q+1])));
        }
        return ans;
    }
    Point poi[Max],convex[Max];
    double Solve(int n)//求出最远点对的平方
    {
        double fpp=0;
        int m=ConvexHull(poi,n,convex);//先找凸包
        fpp=RotateStuck(convex,m);//旋转卡壳求对踵点(可以求出凸包上的最远点对)
        return fpp*fpp;
    }
    int main()
    {
        int t,n;
        double w,x,y;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i=0; i<n; ++i)
            {
                scanf("%lf%lf%lf",&x,&y,&w);
                poi[4*i]=Point(x,y);
                poi[4*i+1]=Point(x+w,y);
                poi[4*i+2]=Point(x,y+w);
                poi[4*i+3]=Point(x+w,y+w);
            }
            printf("%.0f
    ",Solve(4*n));
        }
        return 0;
    }
  • 相关阅读:
    ajax 新闻栏目
    ajax 瀑布流实现
    html5 canvas图片渐变
    html5 canvas图片翻转
    html5 canvas图片反色
    ajax 第一个程序
    ajax 新闻栏目
    HDU 1756 Cupid's Arrow( 判断点在多边形的内外 )
    POJ 2356 Find a multiple( 鸽巢定理简单题 )
    HDU 5762 Teacher Bo ( 暴力 )
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/6234841.html
Copyright © 2011-2022 走看看