解题思路
这是一个二分查找问题。需要找到最小的灯光覆盖距离d,使得所有路灯能够覆盖整条街道。
关键点:
- 对路灯位置进行排序
- 使用二分查找确定最小覆盖距离
- 检查给定距离是否可以覆盖整条街
- 处理精度问题
算法步骤:
- 对路灯位置排序
- 二分查找最小覆盖距离
- 验证覆盖的可行性
- 输出保留两位小数的结果
代码
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// 检查给定的覆盖距离是否可行
bool check(vector<int>& lights, int l, double d) {
if (lights[0] > d) return false; // 检查起点
double covered = lights[0] + d;
for (int i = 1; i < lights.size(); i++) {
if (lights[i] - d > covered) return false;
covered = lights[i] + d;
}
return covered >= l; // 检查终点
}
double solve(int n, int l, vector<int>& lights) {
// 对路灯位置排序
sort(lights.begin(), lights.end());
// 二分查找最小覆盖距离
double left = 0, right = l;
while (right - left > 1e-5) { // 精度控制
double mid = (left + right) / 2;
if (check(lights, l, mid)) {
right = mid;
} else {
left = mid;
}
}
return left;
}
};
int main() {
int n, l;
while (cin >> n >> l) {
vector<int> lights(n);
for (int i = 0; i < n; i++) {
cin >> lights[i];
}
Solution solution;
printf("%.2f\n", solution.solve(n, l, lights));
}
return 0;
}
import java.util.*;
public class Main {
static class Solution {
// 检查给定的覆盖距离是否可行
private boolean check(int[] lights, int l, double d) {
if (lights[0] > d) return false; // 检查起点
double covered = lights[0] + d;
for (int i = 1; i < lights.length; i++) {
if (lights[i] - d > covered) return false;
covered = lights[i] + d;
}
return covered >= l; // 检查终点
}
public double solve(int n, int l, int[] lights) {
// 对路灯位置排序
Arrays.sort(lights);
// 二分查找最小覆盖距离
double left = 0, right = l;
while (right - left > 1e-5) { // 精度控制
double mid = (left + right) / 2;
if (check(lights, l, mid)) {
right = mid;
} else {
left = mid;
}
}
return left;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
int l = sc.nextInt();
int[] lights = new int[n];
for (int i = 0; i < n; i++) {
lights[i] = sc.nextInt();
}
Solution solution = new Solution();
System.out.printf("%.2f\n", solution.solve(n, l, lights));
}
sc.close();
}
}
class Solution:
def check(self, lights, l, d):
# 检查给定的覆盖距离是否可行
if lights[0] > d: # 检查起点
return False
covered = lights[0] + d
for i in range(1, len(lights)):
if lights[i] - d > covered:
return False
covered = lights[i] + d
return covered >= l # 检查终点
def solve(self, n, l, lights):
# 对路灯位置排序
lights.sort()
# 二分查找最小覆盖距离
left, right = 0, l
while right - left > 1e-5: # 精度控制
mid = (left + right) / 2
if self.check(lights, l, mid):
right = mid
else:
left = mid
return left
# 持续读取输入直到EOF
while True:
try:
n, l = map(int, input().split())
lights = list(map(int, input().split()))
solution = Solution()
print("{:.2f}".format(solution.solve(n, l, lights)))
except EOFError:
break
算法及复杂度
- 算法:二分查找
- 时间复杂度:,其中 是路灯数量, 是街道长度
- 空间复杂度:,不考虑输入数组