Files
python/TangDou/CSP-J/AcWingTraining/T4/443.cpp

71 lines
2.3 KiB
C++
Raw Normal View History

2025-08-30 18:35:01 +08:00
#include <bits/stdc++.h>
using namespace std;
const int N = 100010; // 定义最大导弹数量
int n; // 导弹数量
int a1, b1, a2, b2; // 两套拦截系统的坐标
// 导弹结构体,存储导弹坐标和到第一套系统的距离平方
struct Node {
int x, y; // 导弹坐标
int d1; // 导弹到第一套拦截系统的距离平方
} a[N];
// 比较函数,用于按距离从大到小排序
bool cmp(Node &a, Node &b) {
return a.d1 > b.d1;
}
/**
* 计算两点间欧几里得距离的平方
* @param x1,y1 第一个点的坐标
* @param x2,y2 第二个点的坐标
* @return 两点间距离的平方
*/
int get_dist(int x1, int y1, int x2, int y2) {
int dx = x1 - x2;
int dy = y1 - y2;
return dx * dx + dy * dy;
}
int main() {
// 输入两套拦截系统的坐标
cin >> a1 >> b1 >> a2 >> b2;
// 输入导弹数量
cin >> n;
// 输入每个导弹的坐标并计算到第一套系统的距离平方
for (int i = 0; i < n; i++) {
int x, y;
cin >> x >> y;
a[i] = {x, y, get_dist(x, y, a1, b1)};
}
// 将导弹按到第一套系统的距离从大到小排序
sort(a, a + n, cmp);
/**
* 算法思路:
* 1. 首先将所有导弹按到第一套系统的距离从大到小排序
* 2. 初始假设所有导弹都由第一套系统拦截,此时第二套系统半径为0
* 3. 遍历导弹,每次将当前导弹交给第二套系统拦截,并更新第二套系统的半径
* 4. 计算此时的总代价(第一套系统拦截剩余导弹的最大半径 + 第二套系统当前半径)
* 5. 在所有可能的分配方案中取最小值
*/
int res = a[0].d1; // 初始值:所有导弹由第一套系统拦截
int d2 = 0; // 记录前i个导弹到第二套系统的最大距离平方
for (int i = 0; i < n; i++) {
// 更新前i个导弹到第二套系统的最大距离平方
d2 = max(d2, get_dist(a[i].x, a[i].y, a2, b2));
// 计算当前分配方案的总代价并取最小值
// a[i+1].d是剩余导弹到第一套系统的最大距离平方(因为已排序)
res = min(res, (i + 1 < n ? a[i + 1].d1 : 0) + d2);
}
// 输出最小代价
printf("%d\n", res);
return 0;
}