每日一题之 hiho216周 Gas station

描述
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值