二分 跳石头 洛谷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; }