思维
经典的二分答案,二分最小距离的最大值。(题目中的M,N和输入描述的不一致,我这儿M代表最多移走M,有N块)
由于题目要求最小距离的最大值,就想到二分,这个题要求的就是最小值的极大化;移动的数目肯定要是M才是最优的,不妨设d是已知的,现在来考虑c(d)怎么来写?
(1).循环算出相邻之间的石头,如果小于d,则移动这块石头;否则就算下一个相邻的石头;
(2).最后考虑移动石头的数目如果小于等于M,则枚举长度偏小了;如果移动石头数目大于M,则枚举长度偏大了。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 5e4 + 5;
int a[MAXN];
int L, M, N;
bool check(int m) {
int cnt = 0;
int st = 0;
for (int i = 1; i <= M; ++i) {
if (a[i] - st <= m) {
cnt++;
} else {
st = a[i];
}
}
return cnt > N;
}
void solve() {
scanf("%d%d%d", &L, &M, &N);
for (int i = 1; i <= M; ++i) {
scanf("%d", &a[i]);
}
a[M + 1] = L;
int l = 0, r = L;
while (r - l > 1) {
int m = (r + l) >> 1;
if (check(m)) {
r = m;
} else {
l = m;
}
}
printf("%d", r);
}
int main() {
solve();
return 0;
}