/*
* Problem :: 1477 / 휴게소 세우기
*
* Kind :: Binary Search
*
* Insight
* - 최댓값의 최솟값을 구한다
* 최솟값의 최댓값을 구한다
* 보통은 이분 탐색으로 풉니다
* by 코드플러스 백준님의 강의 중에서
* + 휴게소가 없는 구간의 길이가 커질수록
* 휴게소를 덜 지어도 된다 => 단조 증가
* # 휴게소가 없는 구간의 길이를 정하고
* 휴게소를 세워서 지어진 휴게소 개수가 M개 이하이면
* 정한 길이를 바탕으로 휴게소를 지을 수 있다
* -> 정한 길이의 최댓값을 이분 탐색을 통해 찾아주자
*
* Point
* - 하한, 상한을 정해야 하는데
* 상한은 초기 시작점, 끝점도 휴게소가 세워진 것으로 가정했을 때
* 각 휴게소에 인접한 휴게소들간의 거리의 최댓값이다
* + 하한은 1 이다 (최소 인접한 휴게소들간의 거리)
* 상한처럼 (똑같은 가정아래) 인접한 휴게소들간의 거리의 최솟값이 아니다!
* 휴게소가 세워지면서 얼마든지 거리가 좁혀질 수 있기 때문이다
* # 괜히 최적화한답시고 하한을 (L+N+M-1)/(N+M) 잡아 고생했다 ㅠㅠ
*
* - 휴게소가 없는 구간의 길이를 m 이라 할때,
* 서로 인접한 어떤 휴게소의 위치가 a, b (a < b) 라면
* 그 사이 세워야 하는 휴게소의 개수는 (b-a-1)/m 이다
* + 처음에는 cpos 라는 현재 위치를 나타내는 변수에
* while 문을 넣어서 cpos += m, cnt++ 라는 로직을 사용했지만
* 처음의 식으로 구하는 것이 훨씬 깔끔하고 직관적이다!
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <algorithm>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N, M, L;
cin >> N >> M >> L;
int A[N+2];
for (int i=1; i<=N; i++)
cin >> A[i];
// Process
A[0] = 0, A[N+1] = L; /* A[0] = 시작점, A[N+1] = 끝점 */
sort(A, A+(N+2));
int l = 1, r = A[0]; /* 하한, 상한 */
for (int i=1; i<N; i++) {
r = max(r, A[i]-A[i-1]);
} r = max(r, L-A[N-1]);
int ans = -1;
while (l <= r) {
int m = (l+r)/2; /* 휴게소가 없는 구간의 길이 */
int cnt = 0; /* 지은 휴게소 개수 */
for (int i=1; i<N+2; i++) {
cnt += (A[i]-A[i-1]-1)/m;
}
if (cnt > M) {
l = m+1;
} else {
ans = m; /* 반드시 M개를 모두 지어야 하는데
* 현재 m 에 맞춰 지은 휴게소 개수 cnt 가 M 이하라면
* 그냥 m 을 유지하게끔 다른 구간에 나머지 휴게소를 적당히 지으면 됨 */
r = m-1;
}
}
// Control : Output
cout << ans << endl;
}
// Helper Functions
/* None */