凸包扫描 + 旋转卡壳 UVALive 4728

来源:互联网 发布:sql数据库课程设计题目 编辑:程序博客网 时间:2024/04/29 17:13

      题意:给n个正方形,求正方形的顶点之间的最大距离。

思路:可以确定的是最远距离的2个点一定在这些正方形的顶点的凸包上的2个点。所以先求一次凸包。 求凸包上2个点的最打距离,实际就是就凸包的直径,有成型的算法。可以用旋转卡壳直接求解。

#include<cstdio>#include<algorithm>#include<iostream>#include<cmath>#include<queue>#include<stack>#include<string>#include<cstring>#include<map>#include<vector>#include<set>#include<ctime>#include<stdlib.h>using namespace std;const int mod=99999997;const int mmax=200010;const double eps=1e-8;const double pi=acos(-1.0);const int inf=0x3fffffff;#define debug#define mmax 200010//typedef __int64 LL;int sgn(double x){    if(fabs(x)<eps)        return 0;    return x>0?1:-1;}struct Point{    int x,y;    Point(int x=0,int y=0): x(x),y(y) {}    void read()    {        scanf("%d %d",&x,&y);    }};bool operator < (const Point &a,const Point &b){    return a.x<b.x || (a.x==b.x&&a.y<b.y);}bool operator == (const Point &a,const Point &b){    return a.x-b.x==0 && a.y-b.y==0;}typedef Point Vector;Vector operator + (Vector A,Vector B){    return Vector(A.x+B.x,A.y+B.y);}Vector operator - (Vector A,Vector B){    return Vector(A.x-B.x,A.y-B.y);}Vector operator * (Vector A,double k){    return Vector(A.x/k,A.y/k);}Vector operator / (Vector A,double k){    return Vector(A.x/k,A.y/k);}int Dot(Vector A,Vector B){    return A.x*B.x+A.y*B.y;}int Length(Vector A){    return Dot(A,A);}int Cross(Vector A,Vector B){    return A.x*B.y-A.y*B.x;}int ConvexHull(Point *p,int n,Point *Poly){    sort(p,p+n);    n=unique(p,p+n)-p;    int m=0;    for(int i=0;i<n;i++)    {        while(m>1 && Cross(Poly[m-1]-Poly[m-2],p[i]-Poly[m-2])<=0) m--;        Poly[m++]=p[i];    }    int k=m;    for(int i=n-2;i>=0;i--)    {        while(m>k && Cross(Poly[m-1]-Poly[m-2],p[i]-Poly[m-2]) <=0 ) m--;        Poly[m++]=p[i];    }    if(n>1) m--;    return m;}double Angle(Vector v){    double ang=atan2(v.y,v.x);    while(ang<0)        ang+=2.0*pi;    return ang;}//旋转卡壳int RotateStuck(int m,Point * Poly){    int i=0,j=0;    double angi=0.0,angj=pi;    for(int k=0;k<m;k++)    {        if(Poly[k].y<Poly[i].y)            i=k;        if(Poly[k].y>Poly[j].y)            j=k;    }    int m_dis=Length(Poly[i]-Poly[j]);    int cnt=0;    while(sgn(angi-pi)<=0)    {        double dangi=Angle(Poly[(i+1)%m]-Poly[i])-angi;        double dangj=Angle(Poly[(j+1)%m]-Poly[j])-angj;        if(dangi<0)            dangi+=2.0*pi;        if(dangj<0)            dangj+=2.0*pi;        if(sgn(dangi-dangj)==0)        {            m_dis=max(m_dis,Length(Poly[(i+1)%m]-Poly[(j+1)%m]));            m_dis=max(m_dis,Length(Poly[(i+1)%m]-Poly[j]));            m_dis=max(m_dis,Length(Poly[i]-Poly[(j+1)%m]));            i++,j++;            i%=m,j%=m;            angi+=dangi;            angj+=dangi;        }        else if(sgn(dangi-dangj)<0)        {            i++;            i%=m;            m_dis=max(m_dis,Length(Poly[i]-Poly[j]));            angi+=dangi;            angj+=dangi;        }        else if(sgn(dangi-dangj)>0)        {            j++;            j%=m;            m_dis=max(m_dis,Length(Poly[i]-Poly[j]));            angi+=dangj;            angj+=dangj;        }    }    return m_dis;}Point p[400010],Poly[400010];int main(){    int n,t;    int x,y,r;    cin>>t;    while(t--)    {        cin>>n;        for(int i=0;i<n;i++)        {            scanf("%d %d %d",&x,&y,&r);            p[i]=Point(x+r,y);            p[i+n]=Point(x,y+r);            p[i+2*n]=Point(x,y);            p[i+3*n]=Point(x+r,y+r);        }        int m=ConvexHull(p,4*n,Poly);        printf("%d\n",RotateStuck(m,Poly));    }    return 0;}


0 0
原创粉丝点击