Напишіть програму (або функцію), яка демонструє чотири загальні великі часові складності, залежно від способу її запуску. У будь-якій формі воно має додатне ціле число N, яке, напевно, можна вважати менше 2 31 .
Коли програма запускається в оригінальному вигляді, вона повинна мати постійну складність. Тобто, складність повинна бути Θ (1) або, рівнозначно, Θ (1 ^ N) .
Коли програма перевернута і запущена, вона повинна мати лінійну складність. Тобто, складність повинна бути Θ (N) або, рівнозначно, Θ (N ^ 1) .
(Це має сенс , так якN^1
це1^N
навпаки.)Коли програма в два рази , тобто зчеплені до себе, і працювати вона повинна мати експонентну складність, а саме 2 N . Тобто складність повинна бути Θ (2 ^ N) .
(Це має сенс , тому що2
в2^N
два рази перевищує1
в1^N
.)Коли програма подвоюється та обертається та запускається, вона повинна мати складність поліномів , зокрема N 2 . Тобто складність повинна бути Θ (N ^ 2) .
(Це має сенс , так якN^2
це2^N
навпаки.)
Ці чотири випадки - єдині, з якими вам потрібно займатися.
Зауважте, що для точності я використовую нотацію великої тети (Θ) замість великої O, оскільки час виконання ваших програм повинен бути обмежений вище і знизу необхідними складностями. В іншому випадку просто написання функції в O (1) задовольнило б усі чотири бали. Тут не надто важливо зрозуміти нюанс. В основному, якщо ваша програма виконує k * f (N) операції для деякої постійної k, то це, швидше за все, Θ (f (N)).
Приклад
Якби оригінальна програма була
ABCDE
то запуск його повинен займати постійний час. Тобто, будь то вхід N 1 або 2147483647 (2 31 -1) або якесь значення між ними, воно повинно закінчуватися приблизно за однаковий проміжок часу.
Зворотна версія програми
EDCBA
повинен зайняти лінійний час з точки зору N. Тобто час, необхідний для його припинення, повинен бути приблизно пропорційним N. Отже, N = 1 займає найменше часу, а N = 2147483647 займає найбільше.
Подвоєна версія програми
ABCDEABCDE
повинні приймати два-к-N раз , з точки зору N. Тобто, час, необхідний для завершення повинна бути приблизно пропорційна 2 N . Отже, якщо N = 1 закінчується приблизно через секунду, для закінчення N = 60 буде потрібно більше часу, ніж вік Всесвіту. (Ні, ви не повинні це тестувати.)
Подвоєна і перевернута версія програми
EDCBAEDCBA
має зайняти квадратний час у співвідношенні Н. Тобто час, необхідний для його припинення, повинен бути приблизно пропорційним N * N. Отже, якщо N = 1 закінчується приблизно через секунду, N = 60 знадобиться близько години, щоб припинити.
Деталі
Вам потрібно показати або аргументувати, що ваші програми працюють у складних ситуаціях, про які ви кажете. Надання деяких даних про терміни є хорошою ідеєю, але також спробуйте пояснити, чому теоретично складність є правильною.
Це добре, якщо на практиці час, який проводять ваші програми, не є ідеальним представником їх складності (або навіть детермінованої). наприклад, вхід N + 1 іноді може працювати швидше ніж N.
Навколишнє середовище, в якому ви запускаєте свої програми, має значення. Ви можете зробити основні припущення про те, як популярні мови ніколи навмисно не витрачають час на алгоритми, але, наприклад, якщо ви знаєте, що ваша конкретна версія Java реалізує сортування міхурів замість швидшого алгоритму сортування , то вам слід це врахувати, якщо ви робите будь-яке сортування. .
Припускаючи всі складності тут, ми говоримо про найгірші сценарії , а не найкращі та середні.
Простір складності програм не має значення, лише часова складність.
Програми можуть виводити що завгодно. Важливо лише те, що вони приймають натуральне число N і мають правильні часові складності.
Допускаються коментарі та багаторядкові програми. (Ви можете припустити, що
\r\n
зворотний вміст призначений\r\n
для сумісності з Windows.)
Великі О нагадування
Від найшвидшого до найповільнішого O(1), O(N), O(N^2), O(2^N)
(порядку 1, 2, 4, 3 вище).
Повільні терміни завжди переважають, наприклад O(2^N + N^2 + N) = O(2^N)
.
O(k*f(N)) = O(f(N))
для постійної k. Так O(2) = O(30) = O(1)
і O(2*N) = O(0.1*N) = O(N)
.
Пам'ятайте O(N^2) != O(N^3)
і O(2^N) != O(3^N)
.
Акуратний великий O шпаргалка.
Оцінка балів
Це звичайний код гольфу. Виграє найкоротша оригінальна програма (постійний час) у байтах.
n = input(); for i in xrange(n): pass
має експоненціальну складність, оскільки вона здійснює 2 ** k
кроки, де k = log_2(n)
розмір вводу. Вам слід уточнити, чи так це, оскільки це кардинально змінює вимоги.