二分 跳石头 洛谷P2678

题目链接:https://www.luogu.org/problemnew/show/P2678

题意:n个石头排列在一条线上,起点到终点的距离为L,给出每个石子距起点的距离,你可以移除m个石子,使得最小跳跃距离最大

分析:一看到最小xxxx最大这种字眼,我们就得考虑能不能进行二分,也就是说直接对最小跳跃距离进行二分。

我们的judge函数应该是当前的最小跳跃距离满足移走的石子数目小于m,如果满足就往右边去(这种情况下,还可以继续移,最小跳跃距离肯定比当前大),否则就往左边去。

具体实现直接看代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=1<<30;
const ll maxn=5e4+7;
const double pi=acos(-1);
const int mod=100;
int d[maxn];
int len,n,m,ans;
bool judge(int x){
    int tot=0;//用来计算不合法的 
    int now=0;//记录当前的在哪
    int i=0;//记录上一个是在哪
    for(now=1;now<=n+1;now++){
        if(d[now]-d[i]<x)
            tot++;
        else 
            i=now;
    }
    if(tot>m) return false;
    return true; 
}
int main(){
      cin>>len>>n>>m;
      for(int i=1;i<=n;i++)
        scanf("%d",&d[i]);
    d[n+1]=len;
    int l=0,r=len,ans;
    while(l<=r){
        int mid=(l+r)/2;
        if(judge(mid)){
            ans=mid;
            l=mid+1;
        }
        else{
            r=mid-1;
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2019-07-15 10:02  清酒令  阅读(425)  评论(0编辑  收藏  举报