跳石头
这道题目还是难在check函数。
check思路:遍历数组,如果目前两点距离小于k(带进去的数)就搬走(cnt也就是需要搬几块石头++)否则更新目前位置📍。
1 int check(int k) 2 { 3 int s=0,cnt=0; 4 for(int i=1;i<=m;i++) 5 { 6 if(a[i]-s>=k) s=a[i]; 7 else cnt++; 8 } 9 if(cnt<=n) return 1; 10 else return 0; 11 }
但还是因为我爸的要求来说一说,这道题目是二分答案,边界是(1~l+1),如果check(mid)==1说明还可以搬更大的就让l=mid,否则说明要小一点就让r=mid。
1 while(l1+1!=r) 2 { 3 int mid=(l1+r)/2; 4 if(check(mid)==1) 5 { 6 l1=mid; 7 } 8 else r=mid; 9 }
其他的只有L需要开long long 和 要在a数组中加上起点和终点之外其他的就没了。
程序:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int m,n,a[50009]={0}; 4 long long l; 5 int check(int k) 6 { 7 int s=0,cnt=0; 8 for(int i=1;i<=m;i++) 9 { 10 if(a[i]-s>=k) s=a[i]; 11 else cnt++; 12 } 13 if(cnt<=n) return 1; 14 else return 0; 15 } 16 int main() 17 { 18 scanf("%ld%d%d",&l,&m,&n); 19 a[0]=0; 20 a[n+1]=l; 21 for(int i=1;i<=m;i++) scanf("%d",&a[i]); 22 int r=l+1,l1=1; 23 while(l1+1!=r) 24 { 25 int mid=(l1+r)/2; 26 if(check(mid)==1) 27 { 28 l1=mid; 29 } 30 else r=mid; 31 } 32 printf("%d",l1); 33 return 0; 34 }