1 条题解

  • 0
    @ 2025-3-23 16:23:52

    用自带的全排列函数 next_premutation

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    int p[10];
    int x, y, xx, yy;
    double a[10], b[10];
    double r[10];
    // 计算两个坐标之间的距离
    double len(double x, double y, double xx, double yy)
    {
        return sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        cin >> x >> y >> xx >> yy;
        if (x > xx)
            swap(x, xx);
        if (y > yy)
            swap(y, yy);
        for (int i = 1; i <= n; i++)
            cin >> a[i] >> b[i];
        // 油滴顺序
        for (int i = 1; i <= n; i++)
            p[i] = i;
        double ans = (xx - x) * (yy - y);
        do
        {
            // 第 i 次滴的圆心是第 p[i] 个圆心
            // 计算出来每个圆心的半径
            for (int i = 1; i <= n; i++)
            {
                int now = p[i]; // 当前圆心是 (a[now],b[now])
                r[now] = min(a[now] - x, xx - a[now]);
                r[now] = min(r[now], yy - b[now]);
                r[now] = min(r[now], b[now] - y);
                for (int j = 1; j <= i - 1; j++)
                {
                    int pre = p[j]; // 前面滴过了 (a[pre],b[pre])
                    r[now] = min(r[now], len(a[now], b[now], a[pre], b[pre]) - r[pre]);
                    r[now] = max(0.0, r[now]);
                }
            }
            double now = (xx - x) * (yy - y);
            for (int i = 1; i <= n; i++)
                now -= 3.1415926535 * r[i] * r[i];
            ans = min(ans, now);
        } while (next_permutation(p + 1, p + n + 1));
        cout << fixed << setprecision(0) << ans;
        return 0;
    }
    

    手写全排列

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    int p[10];
    bool vis[10]; // 枚举全排列的过程中标记每个数有没有用过
    int x, y, xx, yy;
    double a[10], b[10];
    double r[10];
    // 计算两个坐标之间的距离
    double len(double x, double y, double xx, double yy)
    {
        return sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
    }
    double ans;
    void dfs(int now)
    {
        if (now == n + 1)
        {
            // 第 i 次滴的圆心是第 p[i] 个圆心
            // 计算出来每个圆心的半径
            for (int i = 1; i <= n; i++)
            {
                int now = p[i]; // 当前圆心是 (a[now],b[now])
                r[now] = min(a[now] - x, xx - a[now]);
                r[now] = min(r[now], yy - b[now]);
                r[now] = min(r[now], b[now] - y);
                for (int j = 1; j <= i - 1; j++)
                {
                    int pre = p[j]; // 前面滴过了 (a[pre],b[pre])
                    r[now] = min(r[now], len(a[now], b[now], a[pre], b[pre]) - r[pre]);
                    r[now] = max(0.0, r[now]);
                }
            }
            double now = (xx - x) * (yy - y);
            for (int i = 1; i <= n; i++)
                now -= 3.1415926535 * r[i] * r[i];
            ans = min(ans, now);
            return;
        }
        // 当前挑选第 now 个数
        for (int i = 1; i <= n; i++)
        {
            if (!vis[i])
            {
                vis[i] = true;
                p[now] = i;
                dfs(now + 1);
                vis[i] = false;
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n;
        cin >> x >> y >> xx >> yy;
        if (x > xx)
            swap(x, xx);
        if (y > yy)
            swap(y, yy);
        for (int i = 1; i <= n; i++)
            cin >> a[i] >> b[i];
        // 油滴顺序
        for (int i = 1; i <= n; i++)
            p[i] = i;
        ans = (xx - x) * (yy - y);
        dfs(1);
        cout << fixed << setprecision(0) << ans;
        return 0;
    }
    
    • 1

    信息

    ID
    1836
    时间
    1000ms
    内存
    128MiB
    难度
    4
    标签
    递交数
    3
    已通过
    2
    上传者