题目来源:poj 3258
这题也是典型的二分法的题目。使最小值最大或者使最大值最小。
具体步骤是:先对读进来的数据进行排序,然后执行二分。二分里的check函数,是把不满足答案的石头撤掉。
参考:https://blog.csdn.net/silent0001/article/details/52045497
#include <iostream>
#include <algorithm>
using namespace std;
int l, n, m;
const int maxn = 50010;
int a[maxn];
bool judge(int distance)
{
int cnt = 0; //满足当前跳跃的最小距离为distance时,需要去掉的石头数目
int start = 0; //落脚点
for (int i = 0; i < n; i++)
{
if (a[i] - start < distance)
{
cnt++;
}
else
{
start = a[i];
}
}
if (l - a[n - 1] < distance) //最后那一跳的距离小于mid是不可以的
{
return false;
}
if (cnt > m) //distance太大了
{
return false;
}
else
{
return true;
}
}
int main()
{
while (cin >> l >> n >> m)
{
int high = 0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a, a + n);
int low = a[0];
for (int i = 1; i < n; i++)
{
low = min(low, a[i] - a[i - 1]);
}
high = l;
int mid = 0;
int ans = 0;
while (low <= high)
{
mid = (low + high) >> 1;
if (judge(mid))
{
low = mid + 1;
ans = mid;
}
else
{
high = mid - 1;
}
}
cout << ans << endl;
}
return 0;
}