[Все темы по размещениям]
Теория: Окулов. Дискретная математика. 2008
Практика: [82. Все строки длины n из k различных символов]
Как и ранее алфавитом будем считать первые k цифр начиная с нуля. Длина размещения равна n. Необходимо по номеру сгенерировать размещение с повторениями в лексикографическом порядке.
Для начала давайте рассмотрим все размещения с повторениями для n = 2 и k = 4:
- 00
- 01
- 02
- 03
- 10
- 11
- 12
- 13
- 20
- 21
- 22
- 23
- 30
- 31
- 32
- 33
Внимательный читатель возможно уже нашел закономерность между порядковым номером и размещением. Если внимательно присмотреться, то можно заметить, что размещения с повторениями это числа в k-ричной системе счисления и их перечисление в лексикографическом порядке полностью совпадает с их перечислением в порядке возрастания.
Проверим наше утверждение на размещении “31”: 314=4*3+1=13. Но размещение “31” соответствует 14 размещению. Номер 13 получился, потому что нумерация размещений изначально начинается с 0.
Данная логика отображена в следующей функции:
- typedef unsigned long long ULL;
- void gen_placement_rep_by_num(vector<int> &cur, ULL num, int n, int k) {
- cur.assign(n,0);
- int pos = n - 1;
- while (num) {
- cur[pos--] = num % k;
- num /= k;
- }
- }
* This source code was highlighted with Source Code Highlighter.
Если значения n и k настолько велики, что не помещаются в unsigned long long необходимо использовать длинную арифметику.
Комментариев нет:
Отправить комментарий