Генерація сполучень

Перегляд у форматі PDF

Надіслати розв'язок

Бали: 3,00 (partial)
Time limit: 0.5s
Memory limit: 256M
Input: stdin
Output: stdout

Problem type

Для вказаних чисел ~N~ і ~K~ виведіть всі зростаючі послідовності довжини ~K~ з чисел ~1..N~ у лексикографічному порядку.

Вхідні дані

В одному рядку через пробіл задані 2 числа: спочатку ~N~, потім ~K~. Гарантовано, що ~1\leqslant K\leqslant N\leqslant 100~. Також гарантовано, що подаватимуться лише такі вхідні дані, для яких відповідь не порожня і не перевищує 2 мегабайти.

Результати

Необхідно вивести всі зростаючі послідовності довжини ~K~ з чисел ~1..N~ у лексикографічному (за числами) порядку. Послідовності виводяться по одній в рядку, числа всередині послідовностей розділяються пробілами.

Приклади

Вхід

5 2

Результат

1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5

Примітки

Під «лексикографічним (за числами) порядком» мається на увазі: спочатку треба виводити всі зростаючі послідовності, де на першому (крайньому зліва) місці 1, потім усі, де на першому місці 2, тощо. У свою чергу, всі зростаючі послідовності, де перші числа однакові між собою, мають бути відсортовані за другими числами; всі, де однакові як перші так і другі числа, мають бути відсортовані за третіми; тощо.

Примітка «за числами» означає, що якби спочатку сформували всі послідовності як рядки, і відсортували рядки, то порядок виявився б таким самим при ~n\leqslant 9~, але при ~n\geqslant 10~ з'являється відмінність. У цій задачі потрібно виводити послідовності, що починаються з 10, після послідовностей, що починаються з 9, а якби поформували рядки й відсортували їх як рядки, то послідовності, що починаються з 10, потрапили б між послідовностями, що починаються з 1, і послідовностями, що починаються з 2 (що в цій задачі не буде зараховуватися).

Спробуємо порівняти цю задачу «Генерація розміщень» із попередньою задачею «Генерація розміщень». Якщо робити їх рекурсивним перебором (як це й рекомендується), то загальна схема алгоритму для цих двох задач приблизно однакова. Те, що потрібно виводити лише зростаючі послідовності, водночас і полегшує реалізацію в одній частині алгоритма, й ускладнює в іншій. Полегшує тим, що не потрібно зберігати відносно складну інформацію про точний перелік чисел, які вже були використані, а які все ще можна використати далі; замість цього досить знати, що всі подальші числа мусять бути більші за останнє досі використане. Ускладнює тим, що потрібно писати деякі додаткові відтинання перебору гарантовано непотрібних гілок рекурсії, які можна вважати спрощеним аналогом відтинань методу гілок та меж (розгалужень та обмежень, branches and bounds). Наприклад, при ~N=10~, ~K=7~, не буває таких послідовностей, щоб і зростали, і на першому місці було число, строго більше 4 (почавши, наприклад, з 5, і щоразу збільшуючи якнайменше, всього на 1, отримаємо 5 6 7 8 9 10...??? – тобто, починаючи з 5, добудувати послідовність, щоб вийшло 7 різних натуральних чисел, менших або рівних 10, неможливо). От прямо зараз все ще цілком поміщається в обмеження (число 5 цілком собі з проміжку від 1 до 10), але (в чому й полягає часткова аналогія з методом гілок та меж), варто подумати трохи наперед і помітити, що ще шести різних чисел, більших 5, але менших або рівних 10, нема. Якщо не помічати це вчасно, в цій програмі буде перевищення ліміту часу. Дуже істотне. Таке, що якщо програму не обривати насильно, то на деяких із тестів вона не має ніяких шансів скінчити роботу раніше, чим зламається комп'ютер. А правильно написаний перебір, який робить відтинання вчасно, цілком собі вкладається в десяті долі секунди.


Коментарі

Please read the guidelines before commenting.


Ще немає коментарів.