解题思路
这是一道关于几何优化的问题。主要思路如下:
-
问题分析:
- 有两个喷泉和n朵花
- 每个喷泉可以浇到以自己为中心的圆形区域内的花
- 需要确定两个喷泉的半径
和
- 目标是使
最小
-
优化思路:
- 预计算每朵花到两个喷泉的距离平方
- 按照到第一个喷泉的距离排序
- 从后向前遍历,维护第二个喷泉的最大覆盖半径
- 动态更新最优解
-
关键点:
- 无需枚举所有分配方案
- 利用排序减少搜索空间
- 贪心策略优化计算
代码
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, x1, y1, x2, y2;
cin >> n >> x1 >> y1 >> x2 >> y2;
// 存储每朵花到两个喷泉的距离平方
vector<pair<long, long>> v;
for(long i = 0; i < n; i++) {
int xf, yf;
cin >> xf >> yf;
v.push_back({
pow(xf - x1, 2) + pow(yf - y1, 2), // 到第一个喷泉的距离平方
pow(xf - x2, 2) + pow(yf - y2, 2) // 到第二个喷泉的距离平方
});
}
// 按到第一个喷泉的距离排序
sort(v.begin(), v.end());
// 初始化答案和第二个喷泉的最大覆盖半径
long ans = v[n-1].first;
long jMax = v[n-1].second;
// 从后向前遍历
for(int i = n-2; i >= 0; i--) {
ans = min(ans, v[i].first + jMax); // 更新最优解
jMax = max(jMax, v[i].second); // 更新第二个喷泉的最大覆盖半径
}
cout << min(ans, jMax) << endl;
return 0;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int x1 = sc.nextInt(), y1 = sc.nextInt();
int x2 = sc.nextInt(), y2 = sc.nextInt();
// 存储每朵花到两个喷泉的距离平方
List<long[]> flowers = new ArrayList<>();
for(int i = 0; i < n; i++) {
int xf = sc.nextInt(), yf = sc.nextInt();
long d1 = (long)(xf - x1) * (xf - x1) + (long)(yf - y1) * (yf - y1);
long d2 = (long)(xf - x2) * (xf - x2) + (long)(yf - y2) * (yf - y2);
flowers.add(new long[]{d1, d2});
}
// 按到第一个喷泉的距离排序
Collections.sort(flowers, (a, b) -> Long.compare(a[0], b[0]));
long ans = flowers.get(n-1)[0];
long jMax = flowers.get(n-1)[1];
for(int i = n-2; i >= 0; i--) {
ans = Math.min(ans, flowers.get(i)[0] + jMax);
jMax = Math.max(jMax, flowers.get(i)[1]);
}
System.out.println(Math.min(ans, jMax));
}
}
n, x1, y1, x2, y2 = map(int, input().split())
# 存储每朵花到两个喷泉的距离平方
flowers = []
for _ in range(n):
xf, yf = map(int, input().split())
d1 = (xf - x1) ** 2 + (yf - y1) ** 2 # 到第一个喷泉的距离平方
d2 = (xf - x2) ** 2 + (yf - y2) ** 2 # 到第二个喷泉的距离平方
flowers.append((d1, d2))
# 按到第一个喷泉的距离排序
flowers.sort()
# 初始化答案和第二个喷泉的最大覆盖半径
ans = flowers[-1][0]
j_max = flowers[-1][1]
# 从后向前遍历
for i in range(n-2, -1, -1):
ans = min(ans, flowers[i][0] + j_max) # 更新最优解
j_max = max(j_max, flowers[i][1]) # 更新第二个喷泉的最大覆盖半径
print(min(ans, j_max))
算法分析
复杂度分析:
- 时间复杂度:
- 主要是排序的时间复杂度
- 空间复杂度:
- 存储花的距离信息