题目简介:
解析:题目要求求出最短跳跃的最大值,属于二分法中最小值最大化一类。则在主函数中写出对应的二分算法:长度集合为0-len,mid=(L+R+1)/2,利用二分法不断缩小条件范围。
cin>>len>>n>>m;
for(int i=0;i<n;i++)
{
cin>>stone[i];
}
int L=0,R=len;
int mid;//二分法找适合的最短距离的最大值
while(L<R)
{
mid=(L+R+1)/2;
if(check(mid))
L=mid;
else
R=mid-1;
}
cout<<L<<endl;
关于check()函数:check函数用来条件筛选,若符合在至多移走M块岩石的情况,则返回true,说明用于比较的距离d比较小,需要拆掉的岩石少于M,要贪心继续找更大的d,这时候check返回true,主函数内左侧就要缩小至mid。反之说明用于比较的距离d太大了,需要拆掉的岩石多于M,这时候check返回false,主函数内右侧就要缩小至mid-1。
check函数:
bool check(int d)
{
int num=0;
int cur=0;
for(int i=0;i<n;i++)
{
if(stone[i]-cur<d)
num++;
else
cur=stone[i];
}
if(num<=m)
return true;
else
return false;
}
如果stone[i]-cur<d的话需要拆掉stone[i]这块岩石,i++,然后继续看第i+1块岩石需不需要拆掉,否则说明满足d的距离要求了,cur移到这块岩石。
需要注意的是这里起点和终点的岩石是固定的,无法拆除。
完整c++代码:
#include<bits/stdc++.h>
using namespace std;
int stone[1000]={0};
int len;
int n,m;
bool check(int d)
{
int num=0;
int cur=0;
for(int i=0;i<n;i++)
{
if(stone[i]-cur<d)
num++;
else
cur=stone[i];
}
if(num<=m)
return true;
else
return false;
}
int main()
{
cin>>len>>n>>m;
for(int i=0;i<n;i++)
{
cin>>stone[i];
}
int L=0,R=len;
int mid;//二分法找适合的最短距离的最大值
while(L<R)
{
mid=(L+R+1)/2;
if(check(mid))
L=mid;
else
R=mid-1;
}
cout<<L<<endl;
return 0;
}