15届蓝桥杯国赛 立定跳远
问题描述
在运动会上,小明从数轴的原点开始向正方向立定跳远。项目设置了 n 个检查点 a1,a2,...,an 且 ai≥ai−1>0。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时,小明可以自行再增加 m 个检查点让自己跳得更轻松。在运动会前,小明制定训练计划让自己单次跳跃的最远距离达到 L,并且学会一个爆发技能可以在运动会时使用一次,使用时可以在该次跳跃时的最远距离变为 2L。小明想知道,L 的最小值是多少可以完成这个项目?
输入格式
输入共 2 行。第一行为两个正整数 n,m。第二行为 n 个由空格分开的正整数 a1,a2,...,an。
输出格式
输出共 1 行,一个整数表示答案。
样例输入
5 3
1 3 5 16 21
样例输出
3
样例说明
增加检查点 10,13,19,因此每次跳跃距离为 2,2,5,3,3,3,2,在第三次跳跃时使用技能即可。
评测用例规模与约定
对于 20% 的评测用例,保证 n≤102,m≤,ai≤
。
对于 100% 的评测用例,保证 2≤n≤,m≤
,0<ai≤
。
找到一个最小的整数 x
,使得在数组 a
中插入最多 m
个额外的元素后,数组相邻元素之间的差值的最大值不超过 x
#include<iostream>
using namespace std;const int N = 1e5+10;
int n, m;
int a[N]; int check(int x)
{int cnt=0; //统计需要插入的元素数量//对于每一对相邻元素a[i]和a[i-1]//计算需要插入多少元素才能让所有子间隔不超过 x :(gap - 1) / xfor(int i=1; i<=n; ++i){cnt += (a[i]-a[i-1]-1) / x;}return cnt <= m+1;
}int main()
{cin>>n>>m;for(int i=1; i<=n; ++i) cin>>a[i];int l=0, r=1e8+10; //确保覆盖所有可能的 xwhile(l<r){int mid=l+r>>1;//说明当前的 mid可能是一个可行的解,尝试寻找更小的 xif(check(mid)) r = mid;//否则,调整左边界 l = mid + 1,尝试更大的 xelse l = mid+1;}cout<<l;return 0;
}