题目链接:http://poj.org/problem?id=3258
题目描述大致为,在0~L的长度上,有N块石头,可以移走<=M块石头,求得两个石头之间最短距离的最大值。
首先对石头的位置坐标按从小到大排序,之后在0~L的范围内二分每次所走的距离,看是否满足移走石头数<=M的条件,如果移走石头数多于M,则更改上界R,否则更改下界L,逐渐将L,R的范围缩小,最后求得满足题意的答案。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int a[50005];
int s,n,m;
int v[50005];
int work(int mid)
{
int tmp=0;
int ans=0;
for(int i=1;i<=n;i++)
{
if(a[i]-a[tmp]<mid)
ans++;
else tmp=i;
}
if(s-a[tmp]<mid) ans++;
return ans;
}
int main()
{
while(cin>>s>>n>>m)
{
for(int i=1;i<=n;i++)
cin>>a[i];
a[0]=0;a[n+1]=s;
sort(a,a+1+n);
int l=0,r=s;
int mid;
while(l<=r)
{
mid=(l+r)/2;
int step=work(mid);
if(step<=m) l=mid+1;
else r=mid-1;
}
cout<<l-1<<endl;
}
}