Я буду думать, что сочетание - набор нулей и единиц, в котором на i-м месте стоит 0, если i-й буквы нет в сочетании, и 1, если она есть. Тогда, например, (0111) соответствует bcd. Общее число чисел по условию N, число единиц равно K. Этот список упорядочен по убыванию, и нам необходимо найти M-е число в этом списке.Всего число способов выбрать K элементов из N равно C_N^K ("цэ из N по K").Поймем, например, надо ли брать 1-й элемент. Всего сочетаний, где первый элемент взят: C_(N-1)^(K-1) {в самом деле, в этом случае осталось выбрать K-1 из оставшихся N-1}; не взят: C_(N-1)^K. Учитывая, что те, в которые первый элемент входит, идут перед теми, в которые он не входит, решаем: если M > C_(N-1)^(K-1), 1-й элемент не берём, иначе берём.Дальше если 1-й взяли, M оставляем таким же, если нет - уменьшаем на C_(N-1)^(K-1).Процесс повторяем, пока не найдем все буквы.Осталось понять, как считать C_N^K. Исходя из рассуждений выше, C_N^K = C_(N-1)^(K-1) + C_(N-1)^K. Кроме того, C_N^0 = 1 для всех N, C_N^K = 0 при K < 0 или K > N. Пользуясь этим, можно найти все C_N^K.
Не забываем про длинную арифметику: C_N^K может не влезать в обычные типы данных. Я буду писать на PascalABC.NET, там длинная арифметика есть - тип BigInteger, если нет - легко найти, как это писать. (Update: в данном случае всё влезет в longint - биномиальные коэффициенты не превысят 10 миллионов с небольшим). Итак, вот и искомый код:begin var N, K: integer; read(N, K); var M := ReadString().ToBigInteger(); var C: array[,] of BigInteger := new BigInteger[N, K]; for var j := 1 to K - 1 do C[0, j] := 0; for var i := 0 to N - 1 do C[i, 0] := 1; for var i := 1 to N - 1 do for var j := 1 to K - 1 do C[i, j] := C[i - 1, j] + C[i - 1, j - 1]; var possible := 'a'; while K > 0 do begin if M <= C[N - 1, K - 1] then begin write(possible); dec(K); end else M := M - C[N - 1, K - 1]; dec(N); inc(possible); end;end.Без BigInteger:begin var N, K: integer; var M: longint; read(N, K, M); var C: array[,] of longint := new longint[N, K]; for var j := 1 to K - 1 do C[0, j] := 0; for var i := 0 to N - 1 do C[i, 0] := 1; for var i := 1 to N - 1 do for var j := 1 to K - 1 do C[i, j] := C[i - 1, j] + C[i - 1, j - 1]; var possible := 'a'; while K > 0 do begin if M <= C[N - 1, K - 1] then begin write(possible); dec(K); end else M := M - C[N - 1, K - 1]; dec(N); inc(possible); end;end.