题目
一条长l的笔直的街道上有n个路灯,若这条街的起点为0,终点为l,第i个路灯坐标为ai ,每盏灯可以覆盖到的最远距离为d,为了照明需求,所有灯的灯光必须覆盖整条街,但是为了省电,要使这个d最小,请找到这个最小的d。
来源:牛客网
测试用例
输入:
每组数据第一行两个整数n和l(n大于0小于等于1000,l小于等于1000000000大于0)。第二行有n个整数(均大于等于0小于等于l),为每盏灯的坐标,多个路灯可以在同一点。
7 15
15 5 3 7 9 14 0
输出:
输出答案,保留两位小数。
2.50
思路
- 约束:
- 灯光覆盖整条街。
- d能满足要求,且取最小值。
- 路灯照射区域为圆形区域,d可以作为半径。
- 为了使d尽可能小,在满足能够完全覆盖的情况下,需要尽量减少重合区域。
- 我们需要优先满足大间隔的覆盖,之后处理小间隔。
- 我们设计间隔变化的状态转移方程:
- L:左端第一个路灯到道路左端的距离。
- R: 右端第一个路灯到道路右端的距离。
- M: 两端路灯之间的最大距离/2(因为此处两边都有路灯)。
- 此处处理 M M M遇到一些障碍,每次遍历找到最大 M M M明显是不智的。如果我们事先将路灯位置数组 n u m s nums nums排序,我们的 L L L不会频繁变化, M M M也只需要计算新增的间隔与上一步 M M M比较即可。
S o r t ( n u m s ) L = n u m s [ 0 ] − 0 R = l − n u m s [ i ] M = M A X ( n u m s [ i ] − n u m s [ i − 1 ] , M ) d = M A X ( L , R , M ) \begin{aligned} &Sort(nums)\\ L &= nums[0]-0\\ R &= l - nums[i]\\ M &= MAX(nums[i]-nums[i-1],M)\\ d &= MAX(L,R,M) \end{aligned} LRMdSort(nums)=nums[0]−0=l−nums[i]=MAX(nums[i]−nums[i−1],M)=MAX(L,R,M)
import java.util.*;
public class Main{
public static void solve(int n,int l,int[]index){
double L = 0,R = 0,M = 0,d = 0;
Arrays.sort(index);
L = index[0] - 0;
R = l - index[n-1];
double tmp = L>R?L:R;
for(int i=1;i<n;i++){
M = M>(index[i]-index[i-1])/2.0?M:(index[i]-index[i-1])/2.0;
}
d = M>tmp?M:tmp;
System.out.println(String.format("%.2f",d));
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int n = sc.nextInt();
int l = sc.nextInt();
int[] index = new int[n];
for(int i=0; i< n ;i++){
index[i] = sc.nextInt();
}
solve(n,l,index);
}
}
}
温故知新,未央书斋