Блог пользователя Morgan_HackProg

Автор Morgan_HackProg, 11 лет назад, По-русски

Недавно столкнулся с такой задачей: Задано количество неповторяющихся символов латинского алфавита и номер перестановки. Нужно вывести эту перестановку или сказать что такая не существует. Напримет если задано 3 2 Это значит, что используем символы [a,b,c] и нужна вторая перестановка(лексикографическая). Здесь ответ будет: acb Если же например 3 12 то ответа нет, так как 12>3! Вопрос в том как быстро генерировать эту перестановку, намного быстрее чем за N! ?

  • Проголосовать: нравится
  • +2
  • Проголосовать: не нравится

»
11 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

Примерно так: давай будем строить перестановку от начала.
Переберём 1 элемент и для каждого посчитаем номер самого маленького с его участием(для n=5 это будут 12345, 21345, 31245, 41235, 51234). Понятно, что первый элемент будет такой же, как и у минимального большего или равного K. Теперь, зная первую цифру, попытаемся строить дальше.
Можно не перебирать кандидатов, а сразу их считать, простой формулой через деление, тогда будет линия вместо квадрата.

»
11 лет назад, # |
Rev. 2   Проголосовать: нравится +5 Проголосовать: не нравится
  1. напиши простую программу перебора перестановок в лексикографическом порядке.
  2. оцени сколько существует перестановок длины 10 с фиксированным началом в одно число, скажем начинающихся на 1 и на 2.
  3. пойми, что для 1 и 2 количество продолжений совпадает, и оно есть 9! в первом случае это всевозможные перестановки длины 9 из чисел 2..10, во втором случае из чисел 1, 3, 4, ..., 10.
  4. Лексикографический порядок не зависит от набора символов, можно получить скажем 13-ую перестановку из чисел 1..9, а затем "натянуть" на неё нужные числа из имеющегося множества. т.е. например для твоего примера 3 2 и множества чисел (3, 7, 9) ответом будет 3 9 7
  5. Подбираем первое число, оценивая количество перестановок, вычеркиваем её из множества символов и переходим к такой-же задаче с n на единицу меньшим.