一个码头中有N艘船和N个木桩,船的长度为2*X,码头的宽度为M,N个木桩的位置(相对码头左岸的位置)会在数据中给出。船和船之间不能重叠,即每艘船的船头不能超过上一艘船的船尾,当然也不能超出码头的两岸。船和木桩之间用绳子连接,并且1个木桩只能栓1条船,绳子的一头拴在木桩上,另一头拴在船的中间。而船中间到木桩的距离,就是所需的绳子的长度。由你根据给出的条件,排列船的位置,使得所用到的最长的绳子最短。输出这个最短的长度,如果码头排不下所有船则输出-1。
例如:N = 3, X = 2, M = 16。三个木桩的位置为:1 3 14。船的长度为2*X = 4。你可以将三艘船放在2 6 14(指的是船中间所处的位置),这样船和船之间既没有重叠,并且所用的最长的绳子最短,长度为3,即第2艘船到第二根木桩的距离。
Input
第1行:3个数N X M,中间用空格分隔(1 <= N <= 50000, 1 <= X <= 10^9, 1 <= M <= 10^9)。 第2 - N + 1行:每行1个数Pi,对应木桩的位置(0 <= Pi <= Pi+1 <= M),并且给出的数据是有序的。
Output
输出最长绳子的最小值。如果码头排不下所有船则输出-1。
Input示例
3 2 16 1 3 14
Output示例
3
#include <iostream>
using namespace std;
const int MAXN = 50001;
int input[MAXN];
int n, x, m;
bool check(int k)
{
int head = 0;
int tail = 0;
for (int i = 0; i < n; i++)
{
head = tail;
if (head + x <= input[i] - k)
{
head = input[i] - k - x;
tail = head + 2 * x;
}
else if (head + x <= input[i] + k)
{
tail = tail + 2 * x;
}
else
{
return false;
}
}
if (tail > m)
{
return false;
}
return true;
}
int main()
{
cin >> n >> x >> m;
for (int i = 0; i < n; i++)
{
cin >> input[i];
}
if (2*x*n > m)
{
cout << "-1" << endl;
return 0;
}
int result = m;
int left = 0;
int right = m;
while (left <= right)
{
int mid = left + (right-left)/2;
if (check(mid))
{
result = mid;
right = mid - 1;
}
else
{
left = mid + 1;
}
}
cout << result << endl;
return 0;
}