Problem:
Score : 600 points

Problem Statement

You are given an integer sequence A of length N and an integer K.
You will perform the following operation on this sequence Q times:

Choose a contiguous subsequence of length K, then remove the smallest element among the K elements contained in the chosen subsequence (if there are multiple such elements, choose one of them as you like).

Let X and Y be the values of the largest and smallest element removed in the Q operations. You would like X-Y to be as small as possible.
Find the smallest possible value of X-Y when the Q operations are performed optimally.

Constraints

1 \leq N \leq 2000

1 \leq K \leq N

1 \leq Q \leq N-K+1

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K Q
A_1 A_2 ... A_N

Output

Print the smallest possible value of X-Y.

Sample Input 1

5 3 2
4 3 1 5 2

Sample Output 1

1

In the first operation, whichever contiguous subsequence of length 3 we choose, the minimum element in it is 1.
Thus, the first operation removes A_3=1 and now we have A=(4,3,5,2).
In the second operation, it is optimal to choose (A_2,A_3,A_4)=(3,5,2) as the contiguous subsequence of length 3 and remove A_4=2.
In this case, the largest element removed is 2, and the smallest is 1, so their difference is 2-1=1.

Sample Input 2

10 1 6
1 1 2 3 5 8 13 21 34 55

Sample Output 2

7

Sample Input 3

11 7 5
24979445 861648772 623690081 433933447 476190629 262703497 211047202 971407775 628894325 731963982 822804784

Sample Output 3

451211184

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;

namespace ConsoleApplicationABC98D_ {
    class Program {
        static void Main(string[] args) {
            String line;
            line = Console.ReadLine();
            String[] var = line.Split(new char[] { ' ' });
            int N = int.Parse(var[0]);
            int K = int.Parse(var[1]);
            int Q = int.Parse(var[2]);
            line = Console.ReadLine();
            String[] Astr = line.Split(new char[] { ' ' });
            int[] A = new int[N];
            for (int i = 0; i < N; i++) { A[i] = int.Parse(Astr[i]); }


            int[] A0 = (int[])A.Clone();
            Array.Sort(A0);
            int minXmY = A0[A0.Length - 1] - A0[0];

            var A3 = new List<int>();
            var A2 = new List<int>();
            for (int i = N - Q; i >= 0; i--) {
                int Y = A0[i];
                A3.Clear();
                A2.Clear();
                for (int j = 0; j < N; j++) {
                    if (A[j] >= Y) {
                        A2.Add(A[j]);
                    } else {
                        if (A2.Count >= K) {
                            A2.Sort();
                            A3.AddRange(A2.GetRange(0, A2.Count - K + 1));
                        }
                        A2.Clear();
                        if (j >= N - K) { break; }
                    }
                }
                if (A2.Count >= K) {
                    A2.Sort();
                    A3.AddRange(A2.GetRange(0, A2.Count - K + 1));
                }
                if (A3.Count >= Q) {
                    A3.Sort();
                    int XmY = A3[Q - 1] - Y;
                    if (minXmY > XmY) { minXmY = XmY; }
                }
            }

            Console.WriteLine(minXmY.ToString());
        }
    }
}