代码求调,30分,ac必关
查看原帖
代码求调,30分,ac必关
1431759
wendaining楼主2025/1/30 17:44
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+10;
int l,m,n,d[maxn]; //d表示读入的,每个石头离原点的距离
//check函数的逻辑是判断当前的mid是否符合逻辑。当mid作为最短跳跃距离的时候,至少需要取走多少个石头?
//mid越大cnt越大,二者成正比
//如果想要check()返回true的时候二分(可以)左移,也就是right=mid,那么要么是cnt==m,要么是cnt>m,也就是当前mid太大,需要变小
bool check(int mid){ //需要左移的情况下
  int last=0,cnt=0; //last表示上一个未被移除的石头的坐标
  for(int i=1;i<=n;i++){ //遍历中间所有可移除的石头
    if(d[i]-last<mid) cnt++; //如果距离比mid小那就必须移除
    else last=d[i]; //否则保留目前的石头并更新下一个位置
  }
  //检查倒数第二块石头
  if(l-last<mid) return true; //因为终点的石头无法移除,这就意味着mid必须更小
  return cnt>=m;
}
//求最短跳跃距离的最大值
int binarySearch(int left,int right){
  int mid;
  while(left<right){
    mid=left+(right-left)/2;
    if(check(mid)) right=mid; //需要左移
    else left=mid+1;
  }
  return left;
}
signed main(){
  cin>>l>>n>>m;
  d[0]=0,d[n+1]=l; //第0个石头是起点,第n+1个石头是终点,d的下标从0到n+1
  for(int i=1;i<=n;i++) cin>>d[i];
  int ans=binarySearch(0,l);
  cout<<ans;
}
2025/1/30 17:44
加载中...