1 条题解

  • 0
    @ 2024-12-24 9:59:27

    C++ :

    #include <cstdio>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    
    using namespace std;
    
    #define N 50001
    #define INF 1000000
    #define eps 1e-8
    
    struct pt
    {
        int x, y;
    
        bool operator<(const pt& t) const
        {
            return x < t.x;
        }
    
        double dist(const pt& t) const
        {
            return sqrt((x - t.x) * (x - t.x) + (y - t.y) * (y - t.y));
        }
    };
    
    pt a[N], tmp[N];
    
    double f(int l, int r)
    {
        if (r - l < 2)
        {
            if (r == l)
                return INF;
            if (a[l].y > a[r].y)
                swap(a[l], a[r]);
            return INF;
        }
    
        int mid = (l + r) / 2;
        double midx = a[mid].x;
        double ans = min(f(l, mid), f(mid + 1, r));
        double delta = ans / 2 + eps;
    
        double leftmargin = midx - delta, rightmargin = midx + delta;
        {
            int j = mid + 1;
            for (int i = l; i <= mid; ++i)
            {
                if (a[i].x < leftmargin)
                    continue;
                while (j <= r && a[j].y < a[i].y - delta)
                    ++j;
                if (j == r)
                    break;
    
                int jstart = j;
    
                vector<pt> candidates;
                while (j <= r && a[j].y < a[i].y + delta)
                {
                    if (a[j].dist(a[i]) <= delta)
                        candidates.push_back(a[j]);
                    ++j;
                }
    
    
                for (int ii = 0; ii < candidates.size(); ++ii)
                    for (int jj = ii + 1; jj < candidates.size(); ++jj)
                        ans = min(ans, candidates[ii].dist(candidates[jj])
                                + candidates[ii].dist(a[i]) + candidates[jj].dist(a[i]));
                j = jstart;
            }
        }
    
        {
            int i = l;
            for (int j = mid + 1; j <= r; ++j)
            {
                if (a[j].x > rightmargin)
                    continue;
                while (i <= mid && a[i].y < a[j].y - delta)
                    ++i;
                if (i == mid)
                    break;
    
                int istart = i;
    
                vector<pt> candidates;
                while (i <= mid && a[i].y < a[j].y + delta)
                {
                    if (a[i].dist(a[j]) <= delta)
                        candidates.push_back(a[i]);
                    ++i;
                }
                for (int ii = 0; ii < candidates.size(); ++ii)
                    for (int jj = ii + 1; jj < candidates.size(); ++jj)
                        ans = min(ans, candidates[ii].dist(candidates[jj])
                                + candidates[ii].dist(a[j]) + candidates[jj].dist(a[j]));
                i = istart;
            }
        }
    
        int ip = l, jp = mid + 1, c = l;
        while (ip <= mid || jp <= r)
        {
            bool left;
            if (ip > mid)
                left = false;
            else if (jp > r)
                left = true;
            else
                left = a[ip].y < a[jp].y;
            if (left)
            {
                tmp[c++] = a[ip];
                ++ip;
            }
            else
            {
                tmp[c++] = a[jp];
                ++jp;
            }
        }
        for (int i = l; i <= r; ++i)
            a[i] = tmp[i];
    
        return ans;
    }
    
    double baoli(int n)
    {
        int di, dj, dk;
        double ans = INF;
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                for (int k = j + 1; k < n; ++k)
                {
                    double t = a[i].dist(a[j]) + a[i].dist(a[k]) + a[j].dist(a[k]);
                    if (t < ans)
                    {
                        ans = t;
                        di = i;
                        dj = j;
                        dk = k;
                    }
                }
        printf("%d %d %d\n", di, dj, dk);
        return ans;
    }
    
    int main()
    {
        int T;
        scanf("%d", &T);
        for (int cs = 1; cs <= T; ++cs)
        {
            int n;
            scanf("%d", &n);
            for (int i = 0; i < n; ++i)
                scanf("%d%d", &a[i].x, &a[i].y);
            sort(a, a + n);
            double ans = f(0, n - 1);
            printf("Case %d: %.3lf\n", cs, ans);
        }
        return 0;
    }
    
    
    • 1

    信息

    ID
    1502
    时间
    2000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者