题目:
pdf:https://icpcarchive.ecs.baylor.edu/external/47/4728.pdf
给出n个正方形的左下角坐标和边长,求这些正方形的最远点对的距离,输出距离平方和
解题思路:
凸包直径--旋转卡壳裸题。
注意旋转卡壳算法在计算时凸包的点是逆时针的!!!
ac代码:
样例过了就是过了ʕ •ᴥ•ʔ
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int maxn = 400020;
struct Point
{
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
friend bool operator < (Point a, Point b)
{
return a.x == b.x ? a.y < b.y : a.x < b.x;
}
};
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);
}
int dcmp(double x)//精度三态函数(>0,<0,=0)
{
if (fabs(x) < eps)return 0; //等于
else return x < 0 ? -1 : 1;//小于,大于
}
double Dot(Vector a, Vector b)//点积
{
return a.x * b.x + a.y * b.y;
}
double Cross(Vector a, Vector b)//外积
{
return a.x * b.y - a.y * b.x;
}
ll Distance2(Point a, Point b)//两点间距离
{
return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
}
int ConvexHull(Point *p, int n, Point* ch)//凸包,ch存结果
{
sort(p, p+n);//先x后y
int m = 0;//ch存最终的凸包顶点,下标从0开始
for(int i = 0; i < n; i++)
{
//m是待确定的
while(m > 1 && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;
ch[m++] = p[i];
}
int k = m;
for(int i = n-2; i >= 0; i--)
{
while(m > k && dcmp(Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;//同样的方向
ch[m++] = p[i];
}
if(n>1) m--;//m是凸包上的点数+1,相当于n,ch[m]和ch[0]相同,遍历的时候<m即可
return m;//凸包上的点的个数
}
ll diameter2(Point ch[], int n)//返回点集直径的平方
{
if(n==1) return 0;
if(n==2) return Distance2(ch[0], ch[1]);
ll ans = 0;
for(int u = 0, v = 1; u < n; ++u)
{
for(;;)
{
double diff = Cross(ch[u+1]-ch[u], ch[v+1]-ch[v]);//u=n-1,u+1=n,求凸包时ch[m]中存的时ch[0]
if(dcmp(diff) <= 0) {//01在12的左侧或者重合
ans = max(ans, Distance2(ch[u], ch[v]));
if(diff==0) ans = max(ans, Distance2(ch[u], ch[v+1]));//01和12在一条直线上
break;
}
v = (v+1) % n;
}
}
return ans;
}
Point p[maxn], ch[maxn];
int t, n;
int main()
{
//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
scanf("%d", &t);
double x, y, w;
while(t--)
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%lf %lf %lf", &x, &y, &w);
p[(i-1)*4] = Point(x, y);
p[(i-1)*4+1] = Point(x, y+w);
p[(i-1)*4+2] = Point(x+w, y);
p[(i-1)*4+3] = Point(x+w, y+w);
}
int m = ConvexHull(p, n*4, ch);
printf("%lld\n", diameter2(ch, m));
}
return 0;
}