题解
【入门】导弹拦截
1 条题解
-
0
#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