P2678 跳石头

https://www.luogu.com.cn/problem/P2678

关键词:二分套二分,时间复杂度为logL * N * logN

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int ll, n, m, a[50005];
 4 int check(int p){
 5     int ret=0;//统计可以取消的石头数 
 6     for(int i=0; i<n+1; ){//模拟跳石头的过程 ,注意边界i<n+1 
 7         int val=a[i]+p;//以石头i、跳跃距离p 跳石头可以跳得的石头 
 8         int j=upper_bound(a, a+n+1, val)-a;//二分查找大于val的第一个值下标 
 9         ret+=j-i-1;//可以取消的石头数量 
10         i=j;//跳之后到达的目标石头 
11     }
12     return ret;
13 }
14 int main()
15 {
16     cin>>ll>>n>>m;
17     for(int i=1; i<=n; i++)
18         cin>>a[i];
19     a[n+1]=ll;
20     int l=1, r=ll;
21     int ans=ll;//注意特判为,0个石头,移走数目为0 
22     while(l<=r){
23         int mid=(l+r)/2;
24         if(check(mid)>m){//如果以mid大小跳跃结果多余要求数,则说明mid偏大,此处不能是大于等于 
25             ans=mid;
26             r=mid-1;
27         }
28         else
29             l=mid+1;
30     }
31     cout<<ans;
32     return 0;
33  }

 

posted @ 2020-06-30 09:34  TFLSNOI  阅读(156)  评论(0编辑  收藏  举报