[Все темы по перестановкам]
Теория:
1. Меньшиков. Олимпиадные задачи по программированию. 2006
2. Окулов. Дискретная математика. Теория и практика решения задач по информатике. 2008
3. Кнут. Том 4. Выпуск 2. Генерация всех кортежей и перестановок. 2008
Рассмотрим три задачи:
1) Рекурсивный способ генерации всех перестановок с повторениями в лексикографическом порядке
2) Генерация следующей перестановки с повторениями в лексикографическом порядке(next_permutation)
3) Генерация предыдущей перестановки с повторениями в лексикографическом порядке(prev_permutation)
Практика:
Все задачи будем решать на основе 3B-Перестановки(2)
Аналогичные алгоритмы, реализованные ранее относительно перестановок без повторений неприемлемы для перестановок с повторениями. Обратное неверно. Поэтому реализация для предложенных выше задач будет универсальной и будет работать для перестановок без повторений.
1) Рекурсивный способ генерации всех перестановок с повторениями в лексикографическом порядке.
Суть реализации взята из авторского разбора задачи 3B.
[Решение]
2) Генерация следующей перестановки с повторениями в лексикографическом порядке(next_permutation)
- bool next_permutation(string &a) {
-
- int j = n-2;
- while (j!=-1 && a[j] >= a[j+1]) j--;
- if (j == -1)
- return false; // a - last permutation
- int k = n - 1;
- while (a[j] >= a[k]) k--;
-
- swap(a[j],a[k]);
-
- // reverse back [j+1, n-1]
- int l = j + 1, r = n - 1;
- while (l<r)
- swap(a[l++],a[r--]);
- return true;
- }
* This source code was highlighted with Source Code Highlighter.
Данная реализация очень напоминает аналогичную функцию относительно перестановок без повторения. Если хорошенько присмотреться, то строгое сравнение в строках 4 и 8 теперь стало нестрогим.
[Решение]
3) Генерация предыдущей перестановки с повторениями в лексикографическом порядке(prev_permutation)
- bool prev_permutation(string &a) {
-
- int j = n-2;
- while (j != -1 && a[j] <= a[j+1]) j--;
- if (j == -1) return false;
- int k = n - 1;
- while (a[j] <= a[k]) k--;
-
- swap(a[j], a[k]);
-
- int l = j+1, r = n-1;
- while (l<r)
- swap(a[l++],a[r--]);
- return true;
- }
* This source code was highlighted with Source Code Highlighter.
Здесь нужно грамотно обратить все действия, которые использовались при генерации следующей перестановки.
[Решение]
Комментариев нет:
Отправить комментарий