【LA4728】Square(求凸包(多边形)直径----旋转卡壳)

题目:


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;
}
发布了299 篇原创文章 · 获赞 81 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/Cassie_zkq/article/details/100988394