top1编程
← 返回题目
题解

【入门】导弹拦截

1 条题解

  • 0
    @ 2026-7-29 0:17:00
    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <climits>
    using namespace std;
    
    struct Missile {
        long long x, y;
        long long d1, d2; // 到 system1, system2 的距离平方
    };
    
    int main() {
        long long x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
    
        int N;
        cin >> N;
    
        vector<Missile> missiles(N);
        for (int i = 0; i < N; i++) {
            cin >> missiles[i].x >> missiles[i].y;
            // 计算到两个系统的距离平方
            missiles[i].d1 = (missiles[i].x - x1) * (missiles[i].x - x1) +
                             (missiles[i].y - y1) * (missiles[i].y - y1);
            missiles[i].d2 = (missiles[i].x - x2) * (missiles[i].x - x2) +
                             (missiles[i].y - y2) * (missiles[i].y - y2);
        }
    
        // 按 d1 升序排序,便于枚举系统1的半径
        sort(missiles.begin(), missiles.end(), [](const Missile& a, const Missile& b) {
            return a.d1 < b.d1;
        });
    
        long long min_cost = LLONG_MAX;
    
        // 枚举系统1的半径:设为第 i 个导弹的距离平方(即覆盖前 i+1 个)
        // 但注意:系统1可以只覆盖部分导弹,所以我们枚举“系统1的半径恰好为 d1[i]”
        // 然后系统2必须覆盖所有不在系统1覆盖范围内的导弹
    
        // 先预处理:从后往前,维护每个位置开始,到 system2 的最大 d2
        vector<long long> max_d2_from_right(N);
        max_d2_from_right[N - 1] = missiles[N - 1].d2;
        for (int i = N - 2; i >= 0; i--) {
            max_d2_from_right[i] = max(missiles[i].d2, max_d2_from_right[i + 1]);
        }
    
        // 枚举系统1的半径覆盖到第 i 个导弹(包括)
        // 即系统1半径为 missiles[i].d1,覆盖 [0, i]
        // 系统2覆盖 [i+1, N-1],其半径平方为 max_d2_from_right[i+1](若存在)
        for (int i = 0; i < N; i++) {
            long long r1_sq = missiles[i].d1;
            long long r2_sq = 0;
    
            if (i + 1 < N) {
                r2_sq = max_d2_from_right[i + 1];
            } else {
                r2_sq = 0; // 全部被系统1覆盖
            }
    
            min_cost = min(min_cost, r1_sq + r2_sq);
        }
    
        // 边界情况:系统1不覆盖任何导弹,全部由系统2覆盖
        // 即系统1半径为0,系统2半径为所有导弹到 system2 的最大距离
        long long r2_sq_all = max_d2_from_right[0];
        min_cost = min(min_cost, r2_sq_all); // 系统1半径为0的情况
    
        cout << min_cost << endl;
    
        return 0;
    }
    
    • 1