1 条题解

  • 0
    @ 2026-6-19 10:30:51

    📝 题目大意

    给定平面上 NN 个点,对于每个点 ii,找出欧几里得距离最远的另一个点 jj。若存在多个等距最远点,则输出编号最小的那个。

    💡 解题思路

    1. 题目分析:数据范围极小,N100N \leq 100,坐标绝对值 1000\leq 1000,直接 O(N2)O(N^2) 暴力枚举即可。由于只需比较距离大小,比较平方距离即可避免浮点误差。

    2. 算法推导:对于每个点 ii,遍历所有点 jij \neq i,计算平方距离 dist2=(XiXj)2+(YiYj)2dist2 = (X_i - X_j)^2 + (Y_i - Y_j)^2。维护当前最大平方距离 maxDist2 和对应的最远点索引 farthest。当 dist2>maxDist2dist2 > maxDist2 时更新,使用严格大于号 > 而非 >=,这样当多个点距离相等时,只会保留最先遇到(即编号最小)的那个点,自然完成题目要求的"编号最小"的平局处理。

    3. 边界与细节

      • 坐标差最大为 20002000,平方后为 4×1064 \times 10^6,两个坐标平方和最大约 8×1068 \times 10^6,在 int 范围内,但 std.cpp 统一使用 long long 是更稳妥的做法。
      • 输出时索引从 00 转为 11(即 farthest + 1)。
      • 不能将自己(i=ji = j)作为答案,循环中需跳过。

    ⏱️ 复杂度分析

    • 时间复杂度:对每个点 ii 遍历其余 N1N-1 个点,共 N(N1)N(N-1) 次比较,即 O(N2)O(N^2)N100N \leq 100 时仅需约 10410^4 次运算,完全可行。
    • 空间复杂度:仅需存储 NN 个点的坐标,O(N)O(N)

    💻 标准代码 (C++)

    #include <iostream>
    #include <vector>
    #include <cmath>
    using namespace std;
    int main() {
        int N;
        cin >> N;
        vector<int> X(N), Y(N); // 存储所有点的坐标
        for (int i = 0; i < N; i++) {
            cin >> X[i] >> Y[i];
        }
        for (int i = 0; i < N; i++) {
            int farthest = -1;         // 当前最远点的索引(0-based)
            long long maxDist2 = -1;   // 当前最大平方距离
            for (int j = 0; j < N; j++) {
                if (i == j) continue;  // 跳过自身
                long long dx = X[i] - X[j]; // 横坐标差
                long long dy = Y[i] - Y[j]; // 纵坐标差
                long long dist2 = dx * dx + dy * dy; // 平方距离,避免浮点误差
                // 严格大于:等距时保留先遇到的(编号更小)的点
                if (dist2 > maxDist2) {
                    maxDist2 = dist2;
                    farthest = j;
                }
            }
            cout << farthest + 1 << endl; // 转为 1-based 编号输出
        }
        return 0;
    }
    
    • 1

    信息

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