Codeforces — один из самых узнаваемых сайтов для занятий соревновательным программированием и участия в соревнованиях по программированию. Веб-сайт поддерживается большим сообществом разработчиков со всего мира. Будучи новичком на веб-сайте, все выглядит незнакомым, и вам трудно понять, с чего начать. Вы также можете столкнуться с множеством вопросов о том, какие языки программирования использовать, и о других вещах. Я пишу это, так как уже некоторое время прохожу этот путь, и я подумал, что могу помочь вам растопить лед и сказать свое первое слово странному веб-сайту.

Я проведу вас по сайту, пытаясь ответить на вопросы, которые могут возникнуть у вас. Эта статья больше предназначена для разработчиков Python.

Что делает его привлекательным для разработчиков?

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

Возможно, причина того, что графическому интерфейсу не уделялось много внимания, заключается в том, что сообщество больше заботится о содержании. На самом деле, на веб-сайт добавлено много улучшений, но главное блюдо для сообщества — это вклад, связанный с контентом, такой как постановка задач и тестирование.

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

Что же особенного в Codeforces?

  1. Codeforces удобен для людей, которые хотят улучшить свои навыки решения проблем, анализируя формулировку проблемы и придумывая решение таким образом, чтобы имитировать реальную проблему.
  2. Есть много задач, которые помогут вам применить свои навыки информатики, особенно алгоритмы и структуры данных. Есть много тем, которые вы можете классифицировать и пройти, а также учебные пособия, которые помогут вам правильно мыслить, чтобы применить то, что вы узнали, для решения проблемы.
  3. Самое важное в Codeforces — быть конкурентоспособным. Учащиеся, которым нравится быть в конкурентной среде с другими учениками и хотят измерять свой прогресс по отношению к другим, найдут там свою душу. Могу сказать, что вызывает привыкание. Есть глобальные соревнования, которые проводятся раз в две недели, и участники изо всех сил стараются получить хороший рейтинг. Не думайте, что эти состязания только для героев, состязания бывают разного уровня, чтобы вы могли соревноваться с теми, кто не далеко от вас.
  4. Если вы планируете принять участие в глобальном соревновании по программированию (например, ICPC, IEEEXtreme), это отличное место для обучения и моделирования вашего участия.

Должен ли я изучать C++ для начала?

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

Когда мы приступаем к соревновательному программированию, речь идет не только о реализации алгоритма. Специалисты по постановке задач наложат ограничения, чтобы убедиться, что ваш алгоритм не истечет время ожидания или не потребляет много ресурсов памяти, чтобы заставить вас использовать оптимальное решение. Это также влияет на ваш выбор языка программирования, так как время выполнения кода и использование ресурсов памяти различаются от языка программирования к другому в соответствии с архитектурой языка и скрытыми деталями.

Вот некоторые различия между языками:

  • C/C++ обеспечивает наименьшее время выполнения и использование памяти в большинстве случаев, (согласно личному опыту), но некоторые проблемы, которые включают в себя длительную реализацию, могут потребовать много времени для написания кода и отлаживайте, потому что встроенные функции не выполняют все, что вы ожидаете, поэтому вам нужно выполнить некоторые действия вручную. Это отличный выбор, если вы хотите участвовать в официальном конкурсе, но вы должны привыкнуть к одному из них.
  • С другой стороны, Python требует гораздо больше времени для выполнения, но с его помощью вы сможете решить более 70% проблем. Временные границы будут беспокоить вас в некоторых точных задачах, где установщик проблемы, возможно, не принял во внимание разумные временные ограничения. Прекрасная поддержка встроенных возможностей в Python значительно упрощает реализацию, позволяя меньше думать о здравомыслящих операциях, которые заняли бы много времени, если бы вы использовали язык более низкого уровня. Я считаю, что это хороший выбор, если вы готовы тренироваться сами и не слишком заботитесь о том, чтобы стать международным гроссмейстером.
  • Java — еще один хороший выбор для разработчиков, которые уже к нему привыкли. Он имеет большие возможности и гибкий синтаксис, который дает разработчику контроль над своим кодом, но требует больше времени на выполнение по сравнению с другими.

Итак, отвечая на вопрос, нет необходимости изучать C/C++, прежде чем копаться в соревновательном программировании, но если вы хотите освоить соревновательное программирование, вам может понадобиться один из них.

Когда начать?

Когда вы посещаете веб-сайт, вы видите что-то вроде этого: статья, панель навигации, некоторые виджеты справа, где я должен нажать, чтобы получить проблемы для начинающих?

Ну и нет раздела «Задачи для начинающих». Здесь все немного иначе. Если вы нажмете «Набор задач» на панели навигации, отобразятся все задачи из предыдущих конкурсов, отсортированные по времени их выполнения. Каждый вопрос имеет рейтинг, начинающийся с 800, написанного справа. Вопросы с рейтингом 800 должны быть проще, чем вопросы с рейтингом 1000 и так далее.

Для начала вам может понадобиться начать с более организованного ресурса. Есть частные группы, в которых задачи расположены в соответствии с их трудностями и темами. Вот некоторые из них, с которых вы можете начать свое путешествие.

Подумайте о том, чтобы изучить упомянутую тему, прежде чем приступать к проблемам.

Через некоторое время вы сможете решать задачи напрямую из набора задач.

Как писать код?

Теперь приступим к решению нашей первой задачи. Я выбрал эту задачу для целей урока. Вы можете ознакомиться с ним перед завершением статьи.

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

Мы замечаем, что программа выдаст результат, если ввод включает «H», «Q» или «9». Он не выдаст результат в случае «+», потому что он только увеличит переменную, которая не имеет ничего общего с выводом. Итак, мы знаем, что хотим проверить, существует ли какая-либо инструкция, дающая вывод, внутри введенной инструкции.

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

Итак, вот что мы имеем сейчас:

instructions = input()

Теперь нам нужно перебрать каждый символ в строке, чтобы проверить, присутствует ли одна из инструкций, которые мы обсуждали. Я буду использовать простой цикл for.

instructions = input()
for instruction in instructions:
    if instruction in {'H', 'Q', '9'}:
        print("YES")
        break

Итак, мы проверяем, является ли инструкция одной из инструкций, дающих вывод. Теперь, если мы не найдем его, нам нужно напечатать «НЕТ», как описано в утверждении. Для этого в python есть функция, которая позволяет вам добавить оператор else в цикл for, где оператор else выполняется, когда цикл завершается до конца без прерывания. Итак, в нашем примере мы знаем, что если цикл продолжается до конца, это означает, что инструкции, которую мы ищем, отсутствуют, поэтому мы должны вывести «НЕТ».

instructions = input()
for instruction in instructions:
    if instruction in {'H', 'Q', '9'}:
        print("YES")
        break
else:
    print("NO")

Вот и все! Вы написали свое первое решение проблемы Codeforces.

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

instructions = input()
if set(instructions).intersection({'H', 'Q', '9'}):
    print("YES")
else:
    print("NO")

Теперь пришло время представить свое решение. Вы можете отправить, либо загрузив файл кода, либо скопировав код непосредственно на веб-сайт.

Вы увидите этот виджет на правой боковой панели:

Чтобы скопировать и вставить напрямую, щелкните это на панели навигации:

В поле языка вы можете выбрать Python 3 или PyPy 3.9. В большинстве случаев PyPy будет быстрее, и у вас будет меньше проблем с ним.

Подробнее о PyPy

Как работать со сложными входными данными?

Не все входные данные являются строками, иногда вам дается число или много чисел в одной строке или двумерный массив в нескольких строках. Как с этим справиться? Давайте посмотрим.

Предположим, что на входе два слова, каждое из которых находится в отдельной строке. В этом случае мы будем использовать тот же метод input(), но вызовем его дважды. Мы можем вызвать его, пока у нас есть больше строк для чтения.

"""
programming
article
"""

word1 = input()
word2 = input()

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

"""
programming article
"""

word1, word2 = input().split()

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

"""
programming article about codeforces
"""

words = input().split()

# words[0] -> programming
# words[1] -> article
# words[2] -> about

А если у нас есть номер? все в порядке, у нас есть функции int(), float(), которые преобразуют строковое значение в числовое значение, с которым вы можете работать средствами математики.

"""
3
5.68
"""

x = int(input())
y = float(input())

Но что, если у нас много чисел в одной строке? мы хотим использовать split(), но это строковая функция, которая возвращает только список строковых значений. Итак, нам нужен способ преобразовать каждое значение списка в число. Для этого у нас есть специальная функция map(). Он принимает два аргумента: функцию, которую вы хотите применить ко всем элементам, и набор элементов (список). Он возвращает объект карты, который можно присвоить непосредственно переменным или добавить в новый список.

"""
2 3 5
11 99 44 22 66
"""

a, b, c = map(int, input().split())
numbers = list(map(int, input().split()))

Теперь давайте рассмотрим целый пример, где вам даны размеры двумерного массива, а затем вам даны элементы массива на нескольких строках. Как с этим бороться? ничего нового, мы просто будем использовать те же методы и использовать цикл для получения всех строк двумерного массива. Давайте посмотрим:

"""
4 3
1 2 3
9 3 4
8 7 2
1 0 5
"""

rows, columns = map(int, input().split())
arr = [ list(map(int, input().split())) for i in range(rows) ]

Я использовал сокращение для цикла, но вы можете использовать обычный цикл и добавлять каждую строку в массив 2d.

В некоторых задачах первая строка ввода содержит количество тестовых наборов, затем каждый тестовый набор имеет определенный ввод. Давайте поговорим об этой проблеме, например.

Проблема здесь в том, что мы хотим выполнить решение, которое мы написали, количество раз, равное количеству тестовых случаев. Итак, один из подходов заключается в заключении всего кода в цикл for. См. решение ниже:

for t in range(int(input())):
    word1 = input()
    word2 = 'codeforces'
 
    differences = 0
    for i in range(10):
        if word1[i] != word2[i]:
            differences += 1
    print(differences)

Обратите внимание, что если мы удалим первую строку и отступ, код будет отлично работать для одного теста. Таким образом, преимущество этого способа в том, что мне не нужно ничего менять, кроме как обернуть весь код внутри цикла for.

Как вводить/выводить из файла?

В некоторых задачах вы увидите, что вход и выход — это файлы. В этом случае нельзя использовать обычные методы stdin, stdout. В Python есть специальные методы, работающие с файлами, и вы можете использовать их по своему усмотрению.

Есть много способов добиться этого, но я упомяну способы, которые мне кажутся более простыми и ясными.

Существует встроенный модуль Python для чтения ввода из файлов, который называется fileinput. Вы можете использовать его следующим образом:

"""
hello
"""

import fileinput
fin = fileinput.input('scoreboard.in')

text = fin.readline()

Возможно, вам не понравится писать много fin.readline() в коде, если вы привыкли к обычному методу input(). Это решаемо, поскольку вы можете переопределить метод input(), чтобы он работал так, как вы ожидаете:

"""
hello
"""

import fileinput
fin = fileinput.input('scoreboard.in')
input = fin.readline

text = input()

Что касается вывода, вы можете направить вывод в файл, изменив значение sys.stdout в соответствии с выходным файлом.

import sys
fout = open('scoreboard.out', 'w')
sys.stdout = fout

print("Hello, file")

Как я могу повысить свой рейтинг?

После того, как вы какое-то время решали проблемы, вы думаете, что теперь готовы сражаться. Если вы хотите принять участие в конкурсах на официальном сайте, просто нажмите «Конкурсы» на панели навигации. Он покажет вам предстоящие и предыдущие конкурсы. Чтобы принять участие в конкурсе, вы должны зарегистрироваться до закрытия регистрации. Конкурс имеет определенное время, что означает, что вы должны быть готовы в указанное время, чтобы считаться официальным участником. Позже вы можете решить проблемы в любое время, но это не повлияет на ваше официальное участие. После завершения конкурса ваш рейтинг меняется в соответствии с вашим предыдущим рейтингом и рейтингом в конкурсе. Рейтинг может появиться в вашем профиле через некоторое время.

Конкурсанты делятся на ранги в зависимости от их рейтинга. С мая 2018 года пользователи с рейтингом от 1900 до 2099 могут быть оценены как в Div. 1 и разд. 2 конкурса. В то же время отд. 3 создан для пользователей с рейтингом ниже 1600. Также есть Div. 4, который предназначен для пользователей с рейтингом ниже 1400.

Я думаю, что нет необходимости копать глубже, потому что вы обязательно найдете свой путь и станете частью сообщества, если вам понравится тамошняя погода. Эта статья предназначена для людей, которые озадачены и не знают, с чего и как начать, но как только вы встанете на путь, вы сможете многое сделать.

Также обратите внимание, что я не профессиональный конкурентоспособный программист, но я хотел помочь вам в ваших первых шагах, потому что я уже был в вашей ситуации ранее. Удачи!