题目:P2678 [NOIP2015 提高组] 跳石头 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
思路:这道题如果使用暴力搜索直接求解会超时。实际上,我们可以发现,这个所谓的最短跳跃的答案是有一个确定的范围限制的,我们就可以考虑一种另外的方法去解决——枚举答案,并去验证答案是否可行。于是就可以请出二分答案这一做法。通过判断某个长度是否满足移石子数量小于给定数量即可。
注意:起点是0和n+1,看到这可以试着自己去做做。
以下是ac代码(附详细注释)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define lop(i,a,b) for(int i=(a);i<(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define el '\n'
using LL = long long;
const int N=5e4+5;
int l,n,m,d[N];
bool check(int x)//判断是否满足题意
{
int sum=0,cnt=0,temp=0;
rep(i,1,n+1)
{
sum=d[i]-d[temp];//求距离
if(sum<x)
cnt++;//移除石子的数量
else
temp=i;
}
return cnt<=m;//判断数量是否小于题目给定值
}
int search(int l,int r)
{
while(l<r)//二分模板了
{
int mid=l+r+1>>1;
if(check(mid))l=mid;//满足的话继续尝试增大这个值
else r=mid-1;//反之则减小
}
cout<<l;
}
void solve()
{
cin>>l>>n>>m;
rep(i,1,n)cin>>d[i];
d[n+1]=l;//记得把l赋给d[n+1]
search(1,l);
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int t = 1;
//cin>>t;
while(t--)
solve();
return 0;
}