【题目大意】
数轴上有n个石子,第i个石头的坐标为Di,现在要从0跳到L,每次条都从一个石子跳到相邻的下一个石子。现在FJ允许你移走M个石子,问移走这M个石子后,相邻两个石子距离的最小值的最大值是多少。
*0和L也是两块石头!
【思路】
二分最小值检验即可。二分都是套路,然而我写错了,烧 杯 把ub敲成了l,忘记了范围其实是[lb,ub)QAQ
检验部分的套路:last记录上一次跳到的石头,只要当前石头和上一次的石头的距离小于dis,那么就移走这块石头。如果移走的石头>m,就说明不可行。这是目前看来最简洁的写法了。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int MAXN=50000+50; 7 int l,n,m,d[MAXN]; 8 9 int check(int dis) 10 /*这种检验方式在贪心中经常使用*/ 11 { 12 int last=0,tmp=0; 13 for (int i=1;i<=n;i++) 14 { 15 if (d[i]-d[last]<dis) 16 { 17 tmp++; 18 if (tmp>m) return 0; 19 } 20 else last=i; 21 } 22 return 1; 23 } 24 25 void init() 26 { 27 scanf("%d%d%d",&l,&n,&m); 28 for (int i=1;i<=n;i++) scanf("%d",&d[i]); 29 sort(d+1,d+n+1); 30 d[0]=0; 31 d[++n]=l; 32 } 33 34 void bisearch() 35 { 36 int lb=0,ub=l+1; 37 while (lb+1<ub) 38 { 39 int mid=(lb+ub)>>1; 40 if (check(mid)) lb=mid; 41 else ub=mid; 42 } 43 printf("%d",lb); 44 } 45 46 int main() 47 { 48 init(); 49 bisearch(); 50 return 0; 51 }
时间: 2024-10-05 04:58:49