描述
There are N gas stations on a straight, M kilo-meters long highway. The i-th gas station is Ai kilo-meters away from the beginning of the highway. (It is guaruanteed that there is one gas station at each end of the highway)
Now the mayor can build K more gas stations. He wants to minimize the maximum distance between two adjacent gas station. Can you help him?
输入
The first line contains 3 integer N, M, k. (2 <= N <= 1000, 1 <= M, K <= 100000)
The second line contains N integer, A1, A2, … AN. (0 = A1 <= A2 <= … <= AN = M)
输出
The minimized maximum distance rounded to one decimal place.
样例输入
3 10 2
0 2 10
样例输出
2.7
题意:
在一段长为M的公路上现在有N个加油站,且这N个加油站的坐标为A[i],现在要新建k个加油站。使得每两个相邻的加油站之间的最大距离最小。
思路:
二分答案。假设新建K个加油站的答案是F(K),那么函数F(x)显然是单调递减的,也就是新建的加油站最多,答案越小。
于是我们可以用二分答案来求解。假设加油站之间的距离不少于d,那么我们可以根据d求出每个区间中最多新建多少加油站。如果总数小于K,说明答案比d小,否则说明答案不小于d。
直到二分的d的上下界之差足够小时,d即为答案。
注意四舍五入的时候用ceil函数,直接强制int转换会有精度问题。
#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
#include <iomanip>
#include <cmath>
using namespace std;
const double eps = 1e-9;
int n,k;
double m;
vector<double>A;
bool judge(double mid)
{
int cnt = 0;
for (int i = 0; i < n-1; ++i) {
cnt += ceil((A[i+1]-A[i]) / mid) - 1;
}
if (cnt >= k) return true;
else
return false;
}
double Search(double low, double high)
{
double mid;
while(fabs(low-high) > eps) {
mid = (low + high) / 2.0;
//cout << mid << endl;
if (judge(mid)) {
low = mid + eps;
}
else
high = mid - eps;
}
double res = low;
return res;
}
int main()
{
cin >> n >> m >> k;
double x;
for (int i = 0; i < n; ++i) {
cin >> x;
A.push_back(x);
}
double res = Search(0.0,m);
cout<<setiosflags(ios::fixed)<<setprecision(1)<<res<<endl;
return 0;
}