一个寻找最小的尽量大的题目,做这种题目首先要考虑是否可以使用二分验证的方式,因为这种题目的答案在一个单调区间里面寻找。所以可以通过二分答案加一验证的方式快速寻找的答案。
那么要考虑的就是如何验证是否可行,在本题中使用双指针的策略。last保存上一个石头,如果长度符合那么就让last和i都增加,因为已经大于验证的答案了i再向右移动都一定正确,再验证就没有意义了。如果长度不符合,那么就不移动last,这样正好将这个石头错开(相当于删除了)。
#include <bits/stdc++.h>


using namespace std;
const int maxn = 50000+10;
int rock[maxn];
int M;
//验证是否可行,如果可行就让l = mid+1;
bool yanz(int tar, int n){
    int last = 0, cnt = 0;
    for (int i=1;i<=n;i++) {
        if (rock[i]-rock[last]<tar) cnt++;
        else last = i;
    }
    if (cnt<=M) return true;
    else return false;
}

int main() {
    int L, N;
    scanf("%d %d %d", &L, &N, &M);
    for (int i=1;i<=N;i++) {
        scanf("%d", &rock[i]);
    }
    rock[++N] = L;
    int l = 1, r = L;
    while (l<r) {
        int mid = (l+r+1)/2;
        if (yanz(mid, N)) l = mid;
        else r = mid-1;
    }
    cout<<l;
    return 0;
}