版权声明:转载请附上地址 https://blog.csdn.net/weixin_44574520/article/details/87854786
跳石头
题目分析:
一看完这道题,就感觉和这道题非常的像;
想了想,果然是一道二分答案的题;
我们二分答案,跳跃的最短距离,题目中说了必须跳相邻的石头,但我们有m个石头可以移走,意思就是我们可以最多选择m个石头不跳,注意起点到第一个点的距离和最后一个点到终点的距离也要判断;
每次判断当前点的D[i]与上一次跳跃点D[last]的差,如果这个差小于mid,那么这个点就不跳,可以用的搬走石头数减一;如果在循环中可以搬走石头数小于零了,就返回false;
如果这个差大于等于mid,更新last为当前节点;
如果跳到终点,那个可以移走的石头数大于等于零,那么这个mid就可行,继续二分;
Code:
#include <bits/stdc++.h>
using namespace std;
#define maxn 50010
int L,n,m,d[maxn];
inline int read_(){
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
inline void clean_(){
memset(d,0,sizeof(d));
}
inline int pd_(int x){
int size=m,last=0;
for(int i=1;i<=n;i++){
if(d[i]-d[last]>=x) last=i;
else size--;
if(size<0) return 0;
}
if((d[n+1]-d[last])>=x) return 1;
else {
if(size==0) return 0;
if(size>=1) return 1;
}
}
inline void readda_(){
clean_();
L=read_();n=read_();m=read_();
for(int i=1;i<=n;i++) d[i]=read_();
d[n+1]=L;
}
inline void work_(){
int l=0,r=L;
while(l<=r){
int mid=(l+r)>>1;
if(pd_(mid)) l=mid+1;
else r=mid-1;
}
printf("%d",r);
}
int main(){
readda_();
work_();
return 0;
}