71 lines
2.3 KiB
C++
71 lines
2.3 KiB
C++
|
|
#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;
|
|||
|
|
}
|