BZOJ 1650 [Usaco2006 Dec]River Hopscotch 跳石子
【题意概述】
数轴上有n个石子,第i个石头的坐标为Di,现在要从0跳到L,每次跳都从一个石子跳到相邻的下一个石子。现在FJ允许你移走M个石子,问移走这M个石子后,相邻两个石子距离的最小值的最大值是多少。
【题解】
二分答案(二分一个最小值)。check的时候判一下目前的距离是否大于等于mid,不满足就移走当前石子,最后判断移走的石子的个数有没有超过m。
1 #include<cstdio> 2 #include<algorithm> 3 #define rg register 4 #define N 200010 5 using namespace std; 6 int n,m,L,l,r,mid,tmp,last,a[N]; 7 inline int read(){ 8 int k=0,f=1; char c=getchar(); 9 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 10 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 11 return k*f; 12 } 13 inline bool check(){ 14 int cnt=0,sum=0; 15 for(rg int i=1;i<=n;i++){ 16 sum+=a[i]; 17 if(sum<mid) cnt++; 18 else sum=0; 19 } 20 return cnt<=m; 21 } 22 int main(){ 23 L=read(); n=read(); m=read(); 24 for(rg int i=1;i<=n;i++) a[i]=read(); 25 sort(a+1,a+1+n); 26 for(rg int i=1;i<=n;i++){ 27 tmp=a[i]; a[i]=tmp-last; last=tmp; 28 } 29 a[++n]=L-last; 30 l=0; r=L; 31 while(l+1<r){ 32 mid=(l+r)>>1; 33 if(check()) l=mid; else r=mid; 34 } 35 mid=l+1; 36 if(check()) l++; 37 printf("%d\n",l); 38 return 0; 39 }