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