蓝桥杯2024年第十五届决赛真题-立定跳远

题目概述

题目描述

在运动会上,小明从数轴的原点开始向正方向立定跳远。项目设置了 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 ≤ 103,ai ≤ 103。

对于 100% 的评测用例,保证 2 ≤ n ≤ 105,m ≤ 108,0 < ai ≤ 108。

解题思路

首先我们观察到添加检查点我们的跳的最远距离必定减少具有单调性,题目还说可以使用一次技能使用时可以在该次跳跃时的最远距离变为 2L,使用技能时相当于跳了两次,可以想到把这个技能转换成多加一个检查点(我当时打比赛时没有想到QAQ),这个代码很好写的

代码

#include<iostream>
#define int long long
using namespace std;
const int N=1e5+5;
int a[N];
int n,m;
int check(int x)
{
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i]-a[i-1]>=x)//判断两个检查之间还要加几个检查点使得跳的最远距离为X 
		if((a[i]-a[i-1])%x==0)
		ans+=(a[i]-a[i-1])/x-1;
		else
		ans+=(a[i]-a[i-1])/x;
	}
	if(ans<=m+1)//如果加的检查点多了说明跳的最长距离短了返回1 (这里跟m+1进行比较我前面也提了把一次技能转换成了多加一个检查点) 
	return 1;
	else
	return 0;
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	int l=0,r=1e8;
	while(l<r)
	{
		int mid=l+r>>1;
		if(check(mid))
		r=mid;
		else
		l=mid+1;
	}
	cout<<l;
	return 0;
} 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值