解题思路

这是一道关于几何优化的问题。主要思路如下:

  1. 问题分析:

    • 有两个喷泉和n朵花
    • 每个喷泉可以浇到以自己为中心的圆形区域内的花
    • 需要确定两个喷泉的半径
    • 目标是使 最小
  2. 优化思路:

    • 预计算每朵花到两个喷泉的距离平方
    • 按照到第一个喷泉的距离排序
    • 从后向前遍历,维护第二个喷泉的最大覆盖半径
    • 动态更新最优解
  3. 关键点:

    • 无需枚举所有分配方案
    • 利用排序减少搜索空间
    • 贪心策略优化计算

代码

#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))

算法分析

复杂度分析:

  • 时间复杂度:
    • 主要是排序的时间复杂度
  • 空间复杂度:
    • 存储花的距离信息