洛谷p2678跳石头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//基于二分查找实现 时间复杂度O(log2n)
//枚举+检查
#include <bits/stdc++.h>
using namespace std;
int a[50005];
int l,n,m;
int ans;
bool check(int mid){//mid是理想的最短跳跃距离的值 本函数相当于在模拟理想能否实现 实现与否通过返回的结果体现
int i=0,now=0,cnt=0;
while(i<n+1)
{
i++;//先跳出一步
if(a[i]-a[now]<mid){
//搬走石头
cnt++;
}
else{
now=i;//>=mid 跳过来
}
}
if(cnt<=m)
{
return true;//mid小了或者正好
}
else{
return false;//mid大了 降低对mid值的期望值
}
}

int main()
{
//答案范围一定在1到L之间是本题突破口
//相较于贪心 枚举+检查更加适合本题
//从1到l枚举理想的最小跳跃值并检验来得出答案
cin>>l>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
a[n+1]=l;
a[0]=0;
int ll=1,rr=l,mid;
while(ll<=rr)//使用二分查找可以更快找到正确的值
{
mid=(ll+rr)/2;
if(check(mid))
{
ll=mid+1;
//更新答案值 说明当前的mid是一个合理的值 后面也可能找到更合适的
ans=mid;
}
else{
rr=mid-1;
}
}
cout<<ans<<endl;
return 0;
}

本题考察知识:二分查找

[视频内嵌代码]