Files
python/TangDou/CSP-J/AcWingTraining/T4/443.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

71 lines
2.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}