目录
显示
题目链接
https://www.luogu.org/problem/P2678
https://www.luogu.org/problem/P2855
题解
题目要求“最大值最小”,显然可以用二分答案的方法来解决本题,每次二分答案后,计算移走的石头数,如果移走的石头小于 \(m\) 个,则在左半边搜索,否则在右半边搜索。
但注意,终点是 \(n+1\),所以二分的边界条件是 \(l+1<r\)。
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; int stone[400100]; int main() { int i,j,mid; int l,left,r,n,m; scanf("%d%d%d",&l,&n,&m); for(int i=1;i<=n;i++) scanf("%d",&stone[i]); stone[0]=0; stone[n+1]=l; left=0; r=l+1; while(left+1<r) { mid=(left+r)/2; int ans=0; i=0; while(i<=n) { j=i+1; while(stone[j]-stone[i]<mid&&j<=n+1) j++; ans+=j-i-1; i=j; } if(ans<=m)left=mid; else r=mid; } printf("%d",left); return 0; }