
- •Оценка эффективности алгоритмов
- •Целочисленная арифметика
- •Дано натуральное число. Выяснить является ли оно палиндромом, то есть читается справа налево и слева направо одинаково
- •Дано натуральное число. Выяснить соотношение между количествами двоек и пятерок в этом числе
- •Найти самую большую и самую маленькую цифры данного натурального числа
- •Выяснить образуют ли цифры натурального числа возрастающую последовательность
- •Формат входного файла
- •Формат выходного файла
- •Формат входного файла
- •Формат выходного файла
- •Формат входного файла
- •Формат выходного файла
- •Длинная арифметика
- •Выходные данные
- •Задачи Задача 52 Иностранные земли
- •Входные данные.
- •Выходные данные.
- •Формат входного файла
- •Формат выходного файла
- •Задачи Задача 56 Уравнение
- •Решение
- •Одномерные массивы
- •Базовые задачи на массивы
- •Задача 15 Сокращение одночленов
- •Входные данные:
- •Задача 16 Школьный субботник
- •Входные данные:
- •Входные данные:
- •Выходные данные:
- •Примеры
- •Задача 27 Решение систем линейных уравнений на Pascal
- •Двумерные массивы
- •Описание массива
- •Способы создания массива
- •Задачи:
- •Задача 5 Малыш играет в "Морской бой 2" Малыш играет в "Морской бой". Поле для игры представляет собой квадрат
- •Входные данные
- •Выходные данные
- •Задача 26 Шарик в лабиринте
- •Примечание
- •Задача 27 Блохи
- •В первой строке входного файла Input.Txt находится 5 чисел, разделенных пробелом: n, m, s, t, q.
- •Входные данные
- •Выходные данные
- •Примеры
- •Задача 34 Магический квадрат
- •Формат входного файла
- •Формат выходного файла
- •Входные данные
- •Выходные данные
- •Входные данные
- •Выходные данные
- •Рекурсия
- •Комбинаторика
- •2.5. Генерация комбинаторных объектов
- •Множество всех подмножеств
- •Перестановки
- •Размещения
- •Перестановки с повторениями
- •Сочетания с повторениями
- •Перебор
- •Символ o()
- •Отсечение по времени
- •Рассмотрим несколько олимпиадных задач.
- •Шарик в лабиринте
- •Задача 1. Шарик в лабиринте
- •Задача 3 Цепочка слов
- •Входные данные
- •Выходные данные
- •Примеры
- •Формат входного файла
- •Формат выходного файла
- •Примеры
- •Динамическое программирование
- •Задача 8 Гвоздики
- •Задача 13 Лесенки
- •Задача 18 Свинья-копилка
- •Входные данные
- •Выходные данные
- •Задача 13 Лесенки Лесенкой называется набор кубиков, в котором каждый более верхний слой содержит кубиков меньше, чем предыдущий.
- •Задача 18 Свинья-копилка
- •Формат входного файла:
- •Формат выходного файла:
- •Примеры
- •Решение
- •Входные данные:
- •Выходные данные:
- •Формат входа
- •Формат выхода
- •Задача 39 Лесенка-2
- •Входные данные
- •Выходные данные
- •Примеры
- •Системы счисления
- •Задача 11 Троичная сбалансированная система счисления
- •Алгоритм перевода
- •Процедуры и функции для работы с символами и строками
- •Составьте программу, определяющую, является ли введенное слово изображением числа
- •Введите 2 целых числа. Преобразуйте числа в две строки, объедините их в одну строку и выведите результат на экран.
- •Определить количество слов в строке
- •Получите строковой массив из всех слов данной строки
- •Получите строковой массив из всех слов данной строки и
- •Получите строковой массив из всех слов данной строки и
- •Вычислите длину самого короткого и самого длинного слов в строке
- •Подсчитайте количество букв в каждом слове данной строки
- •Дана строка. Определить количество слов этой строки, в которых есть ровно две буквы «е»
- •Составьте программу, удаляющую все лишние пробелы из введенной строки
- •Напишите программу, сортирующую символы введенной с клавиатуры строки в порядке возрастания их номеров в ascii-таблице. Например, если введено: 'cba', в результате надо получить ‘abc’.
- •В тексте, состоящем из маленьких латинских букв , подсчитайте количество гласных букв
- •Заданы фамилия, имя и отчество учащегося, разделенные пробелом. Напечатайте его фамилию и инициалы.
- •Сложное слово состоит из двух частей одинаковой длины и соединительной гласной. Найдите обе части этого слова.
- •Вычеркните из слова х те буквы, которые встречаются в слове z
- •Подсчитайте число различных букв в слове
- •Даны два слова. Составьте программу, определяющую можно или нет из букв слова а составить слово в.
- •Даны два слова. Являются ли они анаграммами
- •Является ли данная строка палиндромом?
- •Задача 4. Сокращение одночленов
- •Входные и выходные данные
- •Это чисто техническая задача на аккуратное программирование.
- •Задача 6 Текст
- •Входной файл Input.Txt в первой строке входного файла находится 5 чисел,разделенных пробелом: n, m, s, t, q.
- •Бинарные деревья. Алгоритм HeapSort
- •Поиск в глубину в графе
- •Алгоритм Флойда поиска кратчайших расстояний и кратчайших путей
- •Бинарные деревья. Алгоритм HeapSort
- •Графызадачи Двоичная куча
- •Примеры задач, которые решаются с помощью двоичной кучи
- •Поиск максимального потока методом Форда-Фалкерсона на Pascal
- •Графызадачи Поиск сильно связанных компонент на Pascal
- •Поиск точек раздела, мостов и двусвязных компонент
- •Идеи алгоритмов
- •Точки раздела
- •Двусвязные компоненты
- •Задача 21 Моя Столица
- •Вычислительная геометрия
- •3. Уравнение прямой 2
- •4. Уравнение прямой проходящей через точку м(х0у0)
- •Формат входного файла
лицей имени Н.И. Лобачевского при КГУ
Михайлин С.И.
Решение олимпиадных задач
по информатике
Казань 2011 г.
ОГЛАВЛЕНИЕ
Введение
Целочисленная арифметика
Одномерные массивы
Двумерные массивы
Рекурсия
Комбинаторика
Перебор
Динамическое программирование
Системы счисления
Строки
Графы
Вычислительная геометрия
Введение
Эта книга для тех кто получает наслаждение от интенсивного умственного труда, для тех кто хочет развить свой интеллект и память и научиться быстро и логично мыслить. Методов тренировки достаточно много. Вам предлагается один из них – решение задач из области олимпиадной информатики.
Когда читаешь книги других авторов, то почти всегда что-то не устраивает или в манере изложения материала или в излишне подробном изложении или в недостаточно подробном. И возникает желание написать свою книгу, в которой тебя все устраивает. Я занимаюсь олимпиадной информатикой достаточно долго, за годы накопился большой практический материал, который собран в этой книге. Цель этой книги – научить решать олимпиадные задачи по информатике. Акцент сделан на разборе задач по различным темам олимпиадной информатики. Теоретический материал тоже есть, но в минимальном объеме. Как невозможно научиться плавать не плавая, так же невозможно научиться решать задачи, не решая их. Порядок работы с книгой предлагается следующий: прочитать теорию, прочитать задачу, разобраться в алгоритме и решении и затем по памяти набрать решение и протестировать его на полной системе тестов. Постепенно изучая темы, пополняя набор алгоритмов и задач, вы будете двигаться вперед к своей цели. Глупо тренироваться только ради тренировки. Обязательно надо участвовать в олимпиадах различного уровня. Успех всегда окрыляет и дает стимул к дальнейшей работе.
Прежде всего об олимпиадных задачах. Прочитав задачу важно понять к какой теме она относится, какой алгоритм решения применить для ее решения, какую структуру данных выбрать. Важно до конца понять, что от вас требуется и решать ту задачу которую вам предложили решить, а не ту которую вы придумали. Задачи можно решать разными алгоритмами и первый пришедший в голову алгоритм не всегда является самым лучшим и эффективным. Если вы не подумали и сразу стали набирать текст программы, то вас могут подстерегать неприятные, неожиданные открытия. И для того чтобы справится с ними, вам придется потратить время, которое на олимпиадах по информатике на вес золота.
Например: простой алгоритм не эффективен на тестах максимальной размерности, не проходит по времени. Это может относиться к переборным алгоритмам, сортировкам, задачам работы со строками, задачам подсчета и другим. Применяя рекурсивную процедуру, внимательно посмотрите, не вычисляете ли вы одно и то же значение слишком много раз, не слишком ли большая глубина рекурсии. Задача может быть решена просто, но не хватает отведенной на задачу памяти. Альтернативный вариант - нет проблемы с решением задачи, если большой по объему файл можно прочитать несколько раз. Но на это может не хватить отведенного времени... Как правило, это и предполагает составитель задачи, отсекая по времени простое решение. Возможно, вы неправильно выбрали структуру данных. Случается, что там, где вы применяли двухмерный массив достаточно одномерного или вообще обойтись без массивов. Не надо торопиться реализовывать первый пришедший в голову алгоритм. Лучше потратить несколько минут на поиск более эффективного алгоритма, чем потом пытаться улучшить первый неэффективный.
Слишком велика разрядность значений. Оцените количество цифр в результате. Если их слишком много, то придется использовать длинную арифметику.
Аналогичная проблема - потеря точности. Известны случаи, когда суммирование последовательности в прямом и обратном порядке из-за ошибок округления приводит к различным результатам. Суммировать необходимо, начиная с меньших значений. Похожая ситуация возникает при подсчете произведений (например, числе сочетаний), когда надо делить факториалы - один на другой. Решение проблемы заключается в группировке множителей таким образом, чтобы полученное в результате перемножений и делений значения оставались целыми и не слишком большими.
Особенно коварны задачи по геометрии. Браться за них лучше, если вы уверены в вашей геометрической подготовке.
Проверяйте предельные случаи при тестировании. Как поведет себя ваша программа когда, например, входная строка пустая или состоит из двух миллионов букв "а"? Или граф окажется состоящим ровно из одной вершины?
Бывают случаи, когда участникам предлагают так называемые задачи-«гробы». Конечно, они имеют - решение, но оно либо основано на какой-либо сложной теории , либо на очень своеобразных структурах данных. Такие задачи обычно решают эвристическими методами или просто делают заглушки, то есть рассматривают частные случаи, в надежде отщипнуть от задачи несколько баллов.По внешнему виду они могут почти не отличаться от обычных и нужен опыт, чтобы распознать их. Любая задача обычно относится к какому-либо классу задач, поэтому полезно знать основные классы задач и типовые приемы их решения.
Решая задачу необходимо выполнить несколько обязательных шагов:
Внимательно, не спеша прочитайте условие задачи, поймите что вам дано и что надо получить. Иногда в какой-нибудь фразе, на первый взгляд малозначительной фразе, кроется ключ к решению задачи.
Отвлекитесь от фабулы задачи, постройте математическую модель и вспомните тот класс стандартных задач и алгоритмов, который связан с данной задачей.
При построении модели получена некоторая математическая задача. Требуется найти ее решение или подсчитать количество решений.
Очень просто олимпиадную задачу по математике превратить в задачу по программированию. И составители этим пользуются. Получаются задачи, имеющие аналитическое решение и решать их перебором безнадежно. Поэтому очень важно иметь хорошую математическую подготовку.
Вспомните аналогичную задачу. Оцените эффективность алгоритма и время на набор и отладку программы.
Может быть понятно, как решать задачу в частном случае. Рассмотрите числовые примеры и попробуйте найти закономерность. Иногда решение исходной задачи буквально вырастает из исследования частных случаев по мере их накопления.
Подумайте, возможно, ли решить более общую задачу и через ее решение получить решение исходной.
Тщательно продумайте структуры данных. Выбор подходящей структуры данных условиях дефицита времени определяет успех работы.
Существует множество способов проектирования программ (восходящий, нисходящий, модульный), необходимо знать и уметь пользоваться в совершенистве хотя бы одним.
Отладка программы - чисто техническая проблема. Тестирование - ответственный этап решения задачи. Надо создать полную систему тестов, учитывающую все возможные случаи и проверить свое решение на всех тестах.
Чтобы научиться решать задачи, надо их решать. В программировании, как и в математике, нет царского пути.
Олимпиады по информатике бывают командные и личные. Поскольку цели этих олимпиад различаются, то их правила имеют существенные отличия, на которые необходимо обращать внимание школьников при подготовке.
Первое: Практически во всех олимпиадах используется автоматизированная проверка решений. Жюри обычно не читает программу, написанную школьником
Схема проверки выглядит так: программа в виде исходного текста предъявляется тестирующей системе, которая:
а) эту программу компилирует (если это невозможно, то решение данной задачи оценивается в 0 баллов);
б) запускает программу, на серии тестов подготовленных жюри, и сравнивает ответы, выданные программой с эталонными ответами (если программа превышает лимит времени, отведенный на один тест, то происходит ошибка времени выполнения и данный тест считается непройденным ).
Второе: Гарантируется, что исходные данные всех задач корректны. Участникам не надо тратить время на проверку правильности поступивших данных.
Третье: Необходимо строго соблюдать формат входных и выходных данных.
Теперь рассмотрим различия в правилах.
Командные олимпиады:
1.Команде из 3 школьников предоставляется 1 компьютер. Это означает, что выбор тактики имеет решающее значение. Компьютер не должен простаивать ни секунды. Распределение ролей в команде надо сделать во время командных тренировок и строго придерживаться наработанной схеме на олимпиаде.
2. Задача засчитывается, если она прошла все тесты и не засчитывается в противном случае. Задачи командной олимпиады требуют максимально аккуратной реализации.
3. Решение можно посылать на проверку в тестирующую систему сколько угодно раз и результат проверки сообщается в реальном времени. Но за каждую попытку добавляется 20 минут штрафного времени.
4. Участникам доступен общий протокол олимпиады в реальном времени. И это позволяет менее опытным участникам видеть, какую задачу успешно смогли решить другие команды и правильно выбрать последовательность решаемых задач.
Личные олимпиады:
1. Количество баллов по задаче зависит от количества успешно пройденных программой тестов. То есть неполное решение, к примеру на небольшом массиве или не предусматривающее всех частных случаев – тоже способно принести участнику какие-то баллы. За полчаса до окончания тура надо постараться написать так называемы «заглушки», то есть частные случаи в тех задачах, которые полностью вы решить не можете.
2. Решения проверяются один раз – по окончании тура.
От школьника требуется умение расположить задачи по уровню сложности
и решать их в порядке возрастания сложности.
Требуется умение создавать полную систему тестов и тестировать свои программы.
Есть отдельные задачи, в которых требуется ответ типа «Да/Нет». Есть умные школьники, которые понимают, что некоторые тесты будут с ответом «Да», а некоторые – с ответом «Нет», и эти школьники пишут программы, которые всегда выводят «Да» или всегда «Нет». Такие решения часто не засчитываются даже в качестве неполных. Поэтому иногда в правилах встречаются оговорки типа «если программа выводит одно и то же при разных исходных данных, то она считается не прошедшей ни одного теста».
Есть чуть более умные школьники, которые, чтобы преодолеть предыдущее ограничение выводят ответ, базирующийся на генераторе случайных чисел. Именно для таких бывает следующая оговорка: «Жюри считает себя вправе перетестировать программу сколько угодно раз и выбрать наихудший вариант по каждому тесту». Это такая замена формулировке «задача будет не засчитана, если на одних и тех же данных программа выдает разные ответы».
Готовится к олимпиадам по информатике можно по следующему плану:
План подготовки к олимпиадам по информатике
Целочисленная арифметика
Алгоритм Евклида. Нахождение НОД(а,b), НОК(a,b) рекурсивная и прямая реализация
Определение простоты числа.
Нахождение всех простых чисел из промежутка (a,b).
Разложение данного натурального числа на простые множители.
Дано разложение данного натурального числа на простые множители. Найти все делители этого числа.
Нахождение всех делителей натурального числа.
Нахождение цифрового корня натурального числа.
Алгоритм Евклида. Нахождение НОД(а,b), НОК(a,b) рекурсивная и прямая реализация
Длинная арифметика:
Считывание длинного числа из файла.
Запись длинного числа в файл.
Сложение двух длинных чисел
Умножение длинного числа на короткое в системе счисления с основанием 1000.
Умножение длинного числа на длинное.
Деление длинного на короткое
Вычисление n! и степени an и чисел Фибоначчи при маленьких и больших значениях a и n, рекурсивная и нерекурсивная реализация.
Индийский алгоритм вычисления an
Даны натуральные числа N и M. Вычислить число сочетаний C из N по M.
Одномерные массивы
Объявление и использование массивов.
Создание массивов:. вручную, по формуле, генератором случайных чисел, чтение из файла
Виды сортировок. Внешняя и внутренняя сортировка
Сортировка выбором.
Сортировка "пузырьком".
Сортировка Шелла.
Сортировка слиянием.
Внешняя сортировка слиянием.
Кучи. Сортировка с помощью кучи.
Сортировка подсчётом.
Хэширующая сортировка.
Цифровая сортировка
Сквозной поиск элемента в массиве.
Бинарный поиск элемента в массиве.
Извлечение корня n-ой степени из данного натурального числа.
Вычисление значения многочлена по схеме Горнера.
Двумерные массивы
1. Создание двумерных массивов.
2. Задачи на двумерные массивы:
Генерация комбинаторных объектов
1. Понятие "комбинаторных" алгоритмов. 2. Получение комбинаторных объектов. 3. Задачи:
Сгенерировать все последовательности длины n из чисел от 1 до k.
Сгенерировать все подмножества n-элементного множества.
Сгенерировать все перестановки чисел от 1 до N.
Сгенерировать все k-элементные подмножества n-элементного множества.
Сгенерировать все представления числа N в виде суммы натуральных чисел.
Код Грея и сходные задачи.
Генерация перестановок методом транспозиции соседних элементов.
Числа Каталана. Расстановка скобок.
Обработка текста
1.Процедуры и функции обработки текста на Паскале
2. Функции eof и eoln. 3. Функции seekeof и seekeoln. 4. Посимвольная обработка текста.
5.Поиск заданной подстроки в тексте. Алгоритм Бойера-Мура и Кнута – Морриса- Пратта. 7. Использование хэш-функции для поиска произвольной подстроки в строке. 8. Рекурсивный синтаксический анализ скобочных выражений.
Динамическое программирование
Концепция динамического программирования Сохранение решений, подзадач, которые приходится решать повторно или несколько раз. Построение динамических таблиц промежуточных результатов.
Примеры:
Числа Фибоначчи.
Задача о мячике на лестнице.
Задача о куче конфет.
Задача о черепахе.
Задача о Роботе.
Задача о радиоактивных отходах.
Задача о числах с не повторяющимися подряд нулями.
Структуры данных
Элементарная структура данных - запись.
Линейный список.
Специальные структуры данных: стек, очередь, дек.
Деревья. Упорядоченные деревья.
Обходы деревьев.
Двоичные деревья, деревья поиска.
Обходы двоичных деревьев.
Поиск элемента в дереве поиска.
Добавление/удаление элемента.
Характеристики кучи.
Геометрия
Логические функции сравнения вещественных чисел
Площадь ориентированного треугольника (многоугольника)
Уравнение прямой проходящей через две точки
Общего вида ax+by+c=0
Каноническое (x-x1)/(x2-x1)=(y-y1)/(y2-y1)
П
араметрическое x:=x1+t(x2-x1);
y:=y1+t(y2-y1);
Уравнение прямой перпендикулярной данной ax+by+c=0 и проходящей через данную точку (x0,y0).
Длина отрезка
Функция принадлежности точки отрезку
Взаимное расположение двух отрезков (все случаи).
Нахождение точки пересечения отрезка и прямой или выяснения того факта, что они не пересекаются.
Нахождение уравнения биссектрис двух пересекающихся прямых.
Нахождение уравнения касательной к окружности (x-x0)2+(y-y0)2=r2 , проходящей через данную точку (x0,y0).
Является ли точка (x0,y0) внутренней для данного произвольного многоугольника.
Формула деления отрезка в данном отношении.
Расстояние от точки до прямой.
Расстояние между двумя параллельными прямыми.
Выяснить, какие стороны выпуклого многоугольника видны из данной точки.
Сортировка вершин выпуклого многоугольника (вершины заданы в произвольном порядке) по синусам углов.
Нахождение уравнения прямой проходящей через точку (x0,y0) и делящей данный выпуклый многоугольник на две равновеликие части.
Дано множество точек. Найти его выпуклую оболочку.
Перебор с возвратом, метод ветвей и границ
Перебор и его значение в программировании.
Методы оптимизации перебора.
Алгоритмы на графах
Способы представления графа.
Обход в глубину.
Обход в ширину.
Кратчайшие пути.
Алгоритм Форда-Беллмана.
Алгоритм Флойда.
Алгоритм Дейкстры
Поиск Эйлерова цикла
Поиск Гамильтонова цикла
Поиск компонент сильной связности
Поиск мостов
Поиск точек сочленения
Поиск максимального потока
Топологическая сортировка.
Поиск максимального паросочетания
При решении любой олимпиадной задачи необходимо оценить ограничения, наложенные н входные данные.Рассмотрим одну задачу, которая иллюстрирует важность такой оценки.
Задача A+B.
Даны целые числа A и B, по модулю не превышающие 32000. Найти их сумму.
Казалось бы, что ничего сложного, однако эта задача не зря дается практически ежегодно на пробных турах олимпиад по программированию.
Дело в ограничении на целые типы в системах программирования Borland Pascal , которые используются школьниками. Тип Integer имеет диапазон значений от -32768 до +32767. Формально, исходные данные вмещаются в тип, но никто не гарантирует что в этот тип поместится сумма. Дело в том, что во многих компиляторах тип результата определяется исключительно типом операндов. То есть если мы складываем два числа типа Integer (int), то и получается число типа Integer (int). И тут происходит переполнение. Школьникам неявно намекают, чтобы они были более внимательны при выборе типов данных внутри программ.
Что касается этой задачи, то необходимо для обоих исходных данных и результата использовать тип longint.
Оценка эффективности алгоритмов
Помимо проверки того, что алгоритм, реализованный школьником в качестве решения способен выдать правильный ответ задачи к при тех или иных исходных данных, при проверке решения также учитывается и время работы программы. Это не значит, то жизненно необходимо во всех без исключения задачах писать оптимальные алгоритмы (которые, зачастую могут отнять много времени на их грамотную реализацию и отладку). Это просто означает, что в некоторых отдельных задачах параметр времени может играть очень важную роль.
Таким образом надо научиться сравнивать разные алгоритмы по их эффективности, для того, чтобы выбрать в нужный момент наиболее подходящий способ решения задачи.
Для оценки эффективности алгоритма применяется функция сложности, обозначаемая O (читается «о большое»).
Функция сложности отражает по какой закономерности будет расти время выполнения программы в зависимости от исходных данных или их количества.
В качестве примера алгоритма, время выполнения которого зависит от исходного данного — алгоритм нахождения всех натуральных делителей числа N. Очевидно, что чем больше число, тем больше шагов цикла будет необходимо сделать. Примером алгоритма, время выполнения которого зависит от количества входных данных будет поиск наибольшего числа в массиве. Чем длиннее массив, тем больше операций сравнения необходимо сделать, чтобы определить какое число является наибольшим.
Функцией сложности алгоритма будем считать O(f(N)) (здесь f() - некоторая функция от исходных данных), если для любого N существует такая константа C, что время выполнения (или количество операций) не превышает Cf(N).
Основными функциями являются:
O(1) — такая функция сложности говорит о том, что время работы программы постоянно при любых исходных данных;
O(N) — количество операций растет пропорционально N (здесь N может быть как параметром задачи, так и количеством элементов в массиве).
O(log N) — количество операций растет пропорционально логарифму N (именно такой сложностью обладает, например, метод половинного деления при поиске элемента в упорядоченном массиве). При увеличении N на порядок количество операций меняется на единицу. Основание логарифма обычно не уточняется, нас интересует характер роста (быстро/медленно), а не точное значение времени.
O(N2) — количество операций растет пропорционально квадрату N. В общем случае может быть O(Nk) в зависимости от сложности задачи.
O(N!) - количество операций растет пропорционально факториалу N.
Здесь существует некоторое количество тонкостей, связанных с тем что не все операции выполняются за одинаковое время, поэтому при оценке временной сложности используются те операции, которые требуют наибольшего времени.
Чаще всего при описании алгоритмов приводится оценка времени их работы в чистом виде, то есть без учета операций ввода/вывода.
Пример: оценим сложность программы, вводящей с клавиатуры массив и находящей в нем наибольший элемент.
Алгоритм состоит из следующих шагов:
ввод массива (надо считать N элементов)
поиск наибольшего элемента (надо сделать N-1 сравнение)
вывод результата (надо вывести одно число или строку).
Сложим количество операций N+(N-1)+1=2N. То есть существует такая константа, что при любом N количество операций не превышает CN. Следовательно, сложность алгоритма равна O(N).
Пример: оценим сложность программы, вводящей с клавиатуры массив и находящей в нем элемент с заданным свойством (например, равный определенному значению).
Алгоритм состоит из следующих шагов:
ввод массива (N операций ввода)
поиск элемента с заданным свойством (как повезет: элемент может находиться как ближе к началу массива, так и в самом конце; если элемента не существует, то необходимо сделать все N сравнений, чтобы в этом убедиться)
вывод результата.
В лучшем случае данный алгоритм потребует N+2 операции (ввод всего массива, единственное сравнение, вывод), в худшем (когда такого элемента нет — 2N+1 операцию). Если N будет большим числом, к примеру порядка 106, то единицей можно пренебречь. Следовательно, сложность алгоритма равна O(N).
Пример: определим функцию сложности алгоритма шифрования слова, длины L методом подстановки. Пусть существует таблица, в которой для каждого символа алфавита записан символ, на который его надо заменить. Обозначим количество букв алфавита S.
Алгоритм состоит из следующих шагов:
ввод слова (одна операция)
цикл по всем символам
для каждого символа найти его замену в таблице (если таблица не упорядочена и не обладает какими-нибудь свойствами, облегчающими поиск, то в худшем случае S операций для одного символа, если искомый элемент находится в самом конце)
вывод найденного символа
конец цикла
Общее количество операций 1+(S+1)*L. В случае достаточно больших S и L единицами можно пренебречь, получится что функция сложности данного алгоритма есть O(S*L).
Пример: определим функцию сложности алгоритма перевода натурального числа N в двоичную систему счисления (без операций ввода и вывода данных).
Алгоритм состоит из следующих шагов:
цикл, пока результат деления числа на 2 не станет равным 0
разделить число на 2 и запомнить остаток
принять результат деления за новое число
конец цикла
Общее количество операций не превышает 1+log2N. Поэтому данный алгоритм имеет сложность O(log N).
Если программа состоит из нескольких частей с различными функциями сложности, то большая функция сложности «поглотит» меньшие. Например, если делается ввод массива O(N), сортировка O(N2) и вывод упорядоченного массива за O(N), то можно сказать, что вся программа имеет сложность O(N2)
Практическое применение знаний о функиях сложности алгоритмов двояко. Во-первых, для какой-то задачи можно выбрать более оптимальный алгоритм, если о нем есть соответствующие данные в литературе. Во-вторых, зная время работы своего решения на одном наборе исходных данных, школьник может примерно прикинуть время работы этой же программы на данных, которые соответствуют максимальным ограничениям по данной задаче.
К оглавлению