1 条题解

  • 0
    @ 2025-4-10 13:14:00

    题意分析

    给定一个点集,判断是否存在一个对称中心点ss,使得对于任意点pp,都能在点集中找到对应的点qq,满足ssppqq的中点。即s=p+q2s = \frac{p + q}{2}

    解题思路

    1. 对称中心性质:如果对称中心ss存在,则所有点必须成对出现,使得ss是它们的中点。如果点数为奇数,则ss必须是中心点(即该点自身对称)。
    2. 验证方法:假设ss是点集中某两个点的中点,或者直接计算所有点的平均中心,然后检查是否所有点都存在对称点。
    3. 优化策略:先对所有点进行排序(先考虑x坐标,再考虑y坐标),算出一个中心点,再对每对点算出其中心点进行比较。需要注意的是,点的数量有可能是奇数,也可能是偶数,

    关键点:对称中心可能由任意两点确定,但只需验证第一个点与其他点的对称中心是否满足全局对称即可。

    C++实现

    cpp

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int MAX = 10005;
    int n, t;
    bool flag;
    struct Point
    {
        double x;
        double y;
    }p[MAX], center;
    int cmp(Point a, Point b)//先按x从大到小排序,若x相等时则按y从大到小排序
    {
        if (a.x == b.x) return a.y > b.y;
        return a.x > b.x ;
    }
    bool Judge()
    {
        int i;
        if (n % 2)
        {
            center.x = 2 * p[n / 2].x;
            center.y = 2 * p[n / 2].y;
        }
        else
        {
            center.x = p[n / 2].x + p[n / 2 - 1].x;
            center.y = p[n / 2].y + p[n / 2 - 1].y;
        }
        for (i = 0; i < n / 2; ++i)
        {
            if (p[i].x + p[n - i - 1].x != center.x || p[i].y + p[n - i - 1].y != center.y)
            {
                return false;
            }
        }
        return true;
    }
    int main()
    {
        int i, j;
        scanf("%d", &t);
        while (t --)
        {
            scanf("%d", &n);
            for (i = 0; i < n; ++i)
            {
                scanf("%lf%lf", &p[i].x, &p[i].y);
            }
            sort(p, p + n, cmp);
            flag = Judge();
            if (flag)
            {
                printf("yes\n");
            }
            else
            {
                printf("no\n");
            }
        }
        return 0;
    }
    
    • 1

    信息

    ID
    1527
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者