解题思路

一段长为 L 的路径上有 N + 2 个点,其中两个点位于路径端点,第 i 个点与第 i+1 个点之间的距离为 jump[i]
最多可以消除 M 个点,但不能消除路径两边的端点。求相邻两点之间最短的距离的最大值。

对相邻两点之间最短距离 mid 使用二分法。显然,mid >= 1mid <= L
如果 jump[i] < mid,消除第 i+1 个点,直至第 i 个点与其后相邻的点的距离 >= mid 停止消除,将消除点的次数累加计入 k
如果 k > M,表示 mid 过大;否则 mid 这个距离是可以实现的。

C++代码

#include<cstdio>
#include<vector>
using namespace std;

int main(){
    int L, N, M;
    scanf("%d%d%d", &L, &N, &M);
    vector<int> D(N+2, 0);
    vector<int> jump(N+1);
    for(int i=1; i<=N; ++i){
        scanf("%d", &D[i]);
        jump[i-1] = D[i] - D[i-1];
    }
    D[N+1] = L;
    jump[N] = L - D[N];

    int left = 1;
    int right = L;
    int ans = 1;
    while(left <= right){
        int mid = left + (right-left)/2;
        int k = 0;
        for(int i=0; i<N+1; ++i){
            if(jump[i] < mid){
                int j=i+1;
                int sum = jump[i] + jump[j];
                ++k;
                while(sum < mid){
                    ++j;
                    ++k;
                    sum += jump[j];
                }
                i = j;
            }
        }
        if(k <= M){
            ans = mid;
            left = mid + 1;
        }
        else{
            right = mid - 1;
        }
    }
    printf("%d\n", ans);
    return 0;
}