#include <iostream>
#include <vector>
// ピースのサイズが minPieceSize 以上になるようにカットして,
// K 回以上カットできるかを調べる関数.
// カットできる場合 true, できない場合 false を返す
bool Check(int minPieceSize, const std::vector<int>& A, int K, int L)
{
// カットした回数
int cutCount = 0;
// 最後にカットした位置 (cm)
int lastCutPos = 0;
// 各切れ目の位置について
for (const auto& a : A)
{
// 現在の位置でカットした場合にできるピースの長さ
const int pieceSize = (a - lastCutPos);
// 現在の位置でカットした場合に残るほうのピースの長さ
const int remaining = (L - a);
// どちらのピースも minPieceSize 以上であれば, そこでカットする
if ((minPieceSize <= pieceSize)
&& (minPieceSize <= remaining))
{
// カット回数を増やす
++cutCount;
// 最後にカットした位置を更新
lastCutPos = a;
}
}
// カットした回数が K 以上なら OK
return (K <= cutCount);
}
int main()
{
// N 個の切れ目, 全体が L cm, 切れ目を K 個選ぶ
int N, L, K;
std::cin >> N >> L >> K;
// 各切れ目の位置 (cm)
std::vector<int> A(N);
for (auto& a : A)
{
std::cin >> a;
}
////////////////////////////////
//
// いわゆる「めぐる式二分探索法」
// https://qiita.com/drken/items/97e37dd6143e33a64c8c
//
// 解答(最も短いピースの長さ)の候補を表す区間を [left, right) として二分探索
int left = 1;
int right = L + 1;
// 解答を 1 つに絞れないうちは繰り返す
while (1 < (right - left))
{
// 試すピースの長さ
const int middle = (left + (right - left) / 2);
if (Check(middle, A, K, L)) // そのピースの長さで成立したら
{
left = middle;
}
else
{
right = middle;
}
}
//
////////////////////////////////
// 解答を出力
std::cout << left << '\n';
}