http://acm.hdu.edu.cn/showproblem.php?pid=4004
/*
输入:
6 1 2
2
25 3 3
11
2
18
输出:
4
11
*/
#include <iostream>
#include <algorithm>
using namespace std;
int L, N, M;
int d[500005];//存储每块石头到河边距离
bool success(int x)
{
int step = 0;
int start = d[0];
if (x * M < L)//当前跳M次能跳的距离小于河宽L,不合法
{
return false;
}
for (int i = 0; i <= N; i++)
{
if (d[i + 1] - d[i] > x)//如果两块石头距离大于当前单步能跳的最远距离,不合法
{
return false;
}
if (d[i] - start <= x && d[i + 1] - start > x)
{
step++;
start =d[i];
}
}
if (d[N + 1] - start > x)//上面循环没有走到最后一步
{
return false;
}
else
{
step++;
}
if (step > M)//大于最大跳跃次数,不合法
{
return false;
}
else
{
return true;
}
}
int main()
{
int ans;
while (scanf("%d%d%d", &L, &N, &M) != EOF)
{
for (int i = 1; i <= N; i++)
{
cin >> d[i];
}
d[N + 1] = L;
sort(d, d + N + 1);//排序
int l = 0, r = L, mid;
//二分法核心
while (l <= r)
{
mid = (l + r) / 2;
if (success(mid))
{
r = mid - 1;//当前解合法说明最优解在左区间
ans = mid;
}
else
{
l = mid + 1;
}
}
}
cout << ans << endl;
return 0;
}