题意:给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; }