随着种树区间的增长,公路上被种上的树的数量单调不降,具有单调性,因此可以使用二分解决。
二分种树区间长度,并O(N)扫一遍工人的种树区间,判断能否种上k棵树,能就减少二分长度,否则增大二分长度。
#include <bits/stdc++.h>
using namespace std;
int n, k;
vector<int> arr;
bool check(int s) {
int la = -1, cnt = 0;
for(int i = 0 ; i < n ; i ++) {
int x = max(la, arr[i]), y = arr[i] + s - 1;
cnt += y - x + 1;
la = y + 1;
}
return cnt >= k;
}
int main()
{
std::ios::sync_with_stdio(false);
cin >> n >> k;
arr.resize(n);
for(int i=0;i<n;++i){
cin>>arr[i];
}
sort(arr.begin(), arr.end());
int l = 1, r = k;
while(l <= r) {
int mid = l + r >> 1;
if(check(mid)) r = mid - 1;
else l = mid + 1;
}
cout<<r+1;
}
长度无限长的公路上,小美雇佣了n位工人来种树,每个点最多种一棵树。
从左向右数,工人所站的位置为a1,a2,...,an。已知每位工人都会将自己所在位置的右侧一段长度的区间种满树,且每位工人的种树区间长度相同。
现在小美希望公路上至少有k棵树,为了节约成本,他希望每位工人种树的区间长度尽可能短,请你帮他求出,工人们的种树区间至少多长,从能使得公路被种上至少k棵树。
第一行输入两个正整数n,k(1≤n,k≤2×105),分别为表示工人的数量,以及小美要求树的最少数量。
第二行输入n个正整数a1,a2,...,an(1≤ai≤2×105),表示每名工人的位置。
在一行输出一个整数,代表工人们最短的种树区间长度。
输入
3 6
1 2 5
输出
3
说明
每位工人种树的区间长度至少为3。
这样以来:
第一名工人种:1,2,3点的树。
第二名工人种:2,3,4点的树。
第三名工人种:5,6,7点的树。
由于每个位置最多种一棵树,因此共有:1,2,3,4,5,6,7这些点有树,满足至少k=6棵树