• Помогите, пожалуйста, решить олимпиадную задачу (9кл). Олимиада уже прошла, но хочется знать решение. Программа на Паскале. Заранее спасибо.

    Петя выписал все сочетания из N первых латинских букв по K букв. В каждом сочетании он выписывал буквы в лексикографическом (словарном) порядке. Сочетания он выписывал в лексикографическом порядке по одному в строке. Надо узнать какое слово записано в M-ой строке.

    Входные данные: целые числа N, K, M (1<=N<=26, 1<=K<=N, а М не превосходит количества всех выписанных сочетаний).

    Выходные данные: вывести М-ое выписанное сочетание.

    Пример:
    вх: 4 2 3
    вых: ad
    Пояснение: все сочетания в порядке их записи: ab ac ad bc bd cd (третьим по счету сочетанием является ad).

Ответы 4

  • Кстати
    • Автор:

      jan
    • 5 лет назад
    • 0
  • Там есть один косяк
    • Автор:

      poppy80
    • 5 лет назад
    • 0
  • var n,k,i,d,m:longint;    b:array[1..26] of boolean;procedure writesymbol(j:longint);beginwrite(chr(ord('a')+j-1));end;procedure print(x:longint);var z,h,p:longint;beginz := 0;p := 0;while true dobeginp := p + 1;if b[p] = false then z := z + 1;if z = x then break;end;x := p;b[x] := true;writesymbol(x);end;function fa_l(a,b:longint):longint;var s,h:longint;begins := 1;for h := a to b do s := s * h;fa_l := s;end;beginread(n,k,m);d := fa_l(n-k+1,n-1);for i := k downto 1 dobeginprint((m - 1) div d + 1);if m mod d = 0 then m := d elsem := m mod d;d := d div (n - (k - i + 1));end;end.
  • Я буду думать, что сочетание - набор нулей и единиц, в котором на 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.
    • Автор:

      kadendukw
    • 5 лет назад
    • 0
  • Добавить свой ответ

Еще вопросы

Войти через Google

или

Забыли пароль?

У меня нет аккаунта, я хочу Зарегистрироваться

How much to ban the user?
1 hour 1 day 100 years