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