4.1. Практические задания с автоматической проверкой

Сформулируем чеклист решения алгоритмической задачи: от разбора условия до анализа вердикта системы проверки.

Чтобы рассказать, как работает наша система автоматической оценки, мы по шагам разберём две простые задачи. А заодно покажем несколько распространённых проблем и способы их преодоления.

Итак, решение задач по программированию состоит из пяти шагов:

  • Разбор условия задачи. Формулировка задачи указывает формат ввода и вывода, ограничения для данных ввода и использования памяти. От вас требуется написать быструю программу, которая уложится в ограничения по времени и использованию памяти.

  • Проектирование алгоритма. Когда вы поняли, в чём состоит задача, начинайте проектировать алгоритм. Не забудьте доказать, что он работает правильно.

  • Реализация алгоритма. Когда алгоритм спроектирован, его можно реализовать в вашем языке программирования.

  • Тестирование и отладка. Тестирование — это искусство поиска багов. Отладка — это искусство устранения багов. Когда программа готова, приступайте к тестированию! А если обнаружите баг — исправьте его и протестируйте программу снова.

  • Отправка программы на оценку. Когда программа протестирована, сдайте её системе оценки. Если вы увидите сообщение OK, значит всё в порядке. Если нет — возвращайтесь к предыдущим шагам.

Пять простых шагов для решения задачи по программированию

Ниже — краткий анонс того, чему мы научимся в этом параграфе.

Разбор условий задачи

Для начала прочтите формулировку задачи. В неё входят описание вычислительной части, ограничения по времени и использованию памяти и несколько демонстрационных тестов. Убедитесь, что вы понимаете, как вывод соотносится с вводом в каждом из демонстрационных примеров.

Если ограничения по времени и памяти не указаны прямо в формулировке задачи, используются следующие значения по умолчанию.

  • Ограничение по времени (с): 1
  • Ограничение памяти: 512 Mb

Проектирование алгоритма

Когда вы разработали алгоритм, докажите, что он работает верно, и попробуйте оценить время выполнения с помощью самых сложных вводных данных, указанных в секции об ограничениях. Если ваш ноутбук выполняет около операций в секунду, и максимальный размер набора данных в описании задачи , тогда алгоритм с квадратичным временем выполнения вряд ли уложится в ограничение по времени (так как ), в то время как решение с временем выполнения сможет это сделать. Тем не менее решение с подойдёт, если и если . Сработать могут даже решения с . Хотя для некоторых трудных задач в книге полиномиальные алгоритмы и остаются неизвестными, решение с временем выполнения может уложиться в ограничение по времени при ниже .

Реализация алгоритма

Начните реализацию алгоритма на одном из языков программирования, которые поддерживаются нашей системой автоматической оценки. Напоминаем, это: C++, Java, Python3.

Для C++, Java, и Python3 есть примеры (авторские решения) с правильным решением задачи, учитывающие ее ограничения. Они тратят максимум 1/3 заданного лимита по времени и максимум 1/2 по памяти.

Тестирование и отладка

Сдавать вашу реализацию на оценку, не проверив ее, — это плохая идея! Начните с маленьких наборов данных и убедитесь, что ваша программа выдаёт верный результат со всеми предложенными наборами данных. Затем проверьте, сколько времени занимает обработка большого набора данных. Для оценки времени выполнения имеет смысл реализовать ваш алгоритм как функцию — например, solve(dataset) — и потом реализовать дополнительную процедуру generate(), которая выдаст большой набор данных.

Например, если ввод задачи — это последовательность целых чисел длиной , тогда сгенерируйте последовательность длиной , передайте ее функции solve() и убедитесь, что программа выдает правильный результат.

Проверьте ограничивающие значения, чтобы можно было гарантировать, что программа правильно обрабатывает и короткие (например, из 2 элементов), и длинные последовательности (например, из элементов). Если последовательность целых чисел от до даётся в качестве ввода — проверьте, как ваша программа ведёт себя с последовательностью или с . После этого проверьте программу на случайном наборе данных. Дополнительно советуем проверить экстремальные случаи: как пустой набор данных, три точки на одной строке, дерево из одного узла и так далее.

Убедившись, что ваша программа выполняет все эти тесты, переходите к стресс-тестированию. Реализуйте медленный, но простой и верный алгоритм. Проверьте, выдают ли две программы одинаковый результат — однако обратите внимание, что это не применимо к задачам, в которых вывод не уникален. Сгенерируйте случайные тестовые сценарии, а также тесты с изменением параметров — например, с использованием только маленького диапазона больших чисел, строки с одной буквой a или только двумя разными буквами (вместо строк, использующих все буквы латинского алфавита) и так далее. Подумайте, какие ещё тесты могут быть в каком-то смысле необычными.

Например, если вы генерируете графы, попробуйте генерировать древовидные, несвязные, полные, двудольные и так далее. Если вы генерируете древовидные графы, попробуйте генерировать пути, двоичные деревья, звезды и так далее. Если вы генерируете целые числа, попробуйте генерировать и простые, и составные числа.

Использование системы проверки

Когда вы закончили тестирование, сдавайте вашу программу на проверку! Перейдите на страницу, где сдаются задания, и создайте новое выполненное задание. Загрузите файл с вашей программой (обязательно загрузите исходный файл, а не готовое приложение). После этого система оценки скомпилирует вашу программу и использует набор тщательно продуманных тестов, чтобы убедиться, что программа выдаёт правильный результат для всех тестов и что она укладывается в ограничения по времени и памяти. В большинстве случаев оценка занимает около минуты, но в редких случаях, когда серверы загружены, может потребоваться больше времени. Пожалуйста, наберитесь терпения. После загрузки решения можно спокойно уходить со страницы.

В качестве результата вы получите обратную связь от системы оценки. Вам нужно получить вердикт OK — он обозначает, что ваша программа прошла все тесты. Сообщения Wrong answer, Time limit exceeded, Memory limit exceeded означают, что программа не прошла тест по одной из этих причин. Если ваша программа дает сбой, проходя один из первых двух тестовых сценариев, система оценки скажет вам об этом и покажет тестовый сценарий и вывод вашей программы. Это должно помочь вам использовать правильный формат ввода/вывода. В остальных случаях система оценки не будет показывать вам тестовый сценарий, который ваша программа не смогла выполнить.

Отмечайте параграфы как прочитанные чтобы видеть свой прогресс обучения

Вступайте в сообщество хендбука

Здесь можно найти единомышленников, экспертов и просто интересных собеседников. А ещё — получить помощь или поделиться знаниями.
Вступить
Сообщить об ошибке
Предыдущий параграф3.6. Рандомизированные алгоритмы

Случайность в действиях алгоритма может приводить к неопределённости в точности результатов или времени работы. В этом параграфе спроектируем и оценим трудоёмкость рандомизированного алгоритма для задачи сортировки.

Следующий параграф4.2. Задача «Сумма двух чисел»

Что может быть проще поиска суммы двух чисел? Для решения задачи не потребуется продвинутых навыков программирования, поэтому сфокусируем внимание на оформлении алгоритма и системе автоматической проверки.