跳石头
传送门:https://www.luogu.org/problemnew/show/P2678
二分答案,先假设最短距离的最大值mid为全长的一半,然后从头开始跳石头,对于两个相距小于mid的石头,将前一个石头移走,统计被移走的石头数目,若数目超过了所规定的数目,则mid不合法,需要减少它的值,继续二分,在[l,mid-1]中找答案;若mid合法,说不定在[mid+1,r]中有比它更优的解,因此再去[mid+1,r]的区间找答案。
附上代码:
#include<cstdio>
using namespace std;
inline int read()
{
static char ch;
while((ch = getchar()) < '0' || ch > '9');
int ret = ch - 48;
while((ch = getchar()) <= '9' && ch >= '0')
ret = ret * 10 + ch - 48;
return ret;
}
int l,n,m,d[500010],ll,rr,ans;
bool check(int mid)
{
int tot = 0;
int now = 0,i = 0;
while(i < n+1)
{
i++;
if(d[i] - d[now] < mid)
{
tot++;
if(tot > m) return false;
}
else now = i;
}
return true;
}
int main()
{
l = read();
n = read();
m = read();
for(int i = 1;i <= n;i++) d[i] = read();
d[n+1] = l;
ll = 1;
rr = l;
while(ll <= rr)
{
int mid = (ll+rr)>>1;
if(check(mid))
{
ans = mid;
ll = mid + 1;
}
else rr = mid - 1;
}
printf("%d",ans);
return 0;
}