一个寻找最小的尽量大的题目,做这种题目首先要考虑是否可以使用二分验证的方式,因为这种题目的答案在一个单调区间里面寻找。所以可以通过二分答案加一验证的方式快速寻找的答案。
那么要考虑的就是如何验证是否可行,在本题中使用双指针的策略。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;
}

京公网安备 11010502036488号