#include <iostream>
using namespace std;
const int N=5e4+10;
int w[N];
int L,n,m;
//check就是模拟的过程 假设目前跳跃距离是mid 看需要移走几块石头
bool check(int mid) //就是个模型的过程 已知mid了
{
int res=0,j=0;//res表示需要移走多少石头 j表示人现在所处的位置
for(int i=0;i<=n;i++) //遍历每个石头以及终点
{
bool flag=false; //当前这块石头移走了吗? 默认没有移走
if(w[i]-j<mid) //当前这块石头和人的距离小于mid了 得移走
{
flag=true; //打上标记 当前这块石头移走了
res++; //需要移走的石头数量+1
if(res>m)return false; //如果需要移走的石头已经大于m了 别继续算了 直接不行
}
if(flag==false)j=w[i]; //如果当前石头没有移走 人就跳到这里
}
return res<=m; //这道题是正相关 所以是求出来的res小于等于题目中给的m
}
//这道题移动石头随着跳跃距离增大而增大,跳的远了,要移走的石头也就多了。
//求最短跳跃距离的最大的值
int main()
{
scanf("%d%d%d",&L,&n,&m);
for(int i=0;i<n;i++)scanf("%d",&w[i]);
w[n]=L;
int l=0,r=L+1;
while(l+1<r)
{
int mid=l+r>>1;
if(check(mid))l=mid; //最大化 就是要求最大值
else r=mid;
}
printf("%d",l); //if语句后面是l 当然就打印l
return 0;
}