Рекомендации по составлению задач: различия между версиями

Материал из Олимпиадное программирование в УлГТУ
Перейти к навигации Перейти к поиску
(Новая страница: «= Условия = == Раздел «Входные данные» == === Структура раздела === Если все данные вводятся в…»)
 
 
(не показано 8 промежуточных версий этого же участника)
Строка 1: Строка 1:
= Условия =
* [https://codeforces.com/blog/entry/1392 Акользин И. Пара слов о том, как правильно готовить условия задач]
* [http://webcache.googleusercontent.com/search?q=cache:zcSOEvfR768J:codeforces.com/blog/entry/9592%3Flocale%3Dru+&cd=1&hl=en&ct=clnk&gl=ru Рубинчик М. Системные проблемы АСМ. Оформление условий задач]
* [https://docs.google.com/document/pub?id=12KYV_jWXil6FRMkZIH98UH5vzA48Qy9TdONgc0OoFfQ Станкевич А. Правила подготовки задач]
* [https://docs.google.com/document/d/e/2PACX-1vRhazTXxSdj7JEIC7dp-nOWcUFiY8bXi9lLju-k6vVMKf4IiBmweJoOAMI-ZEZxatXF08I9wMOQpMqC/pub Правила подготовки задач для раундов Codeforces]


== Раздел «Входные данные» ==
== Раздел «Входные данные» ==


=== Структура раздела ===
Описание формата входных данных — самая формализованная часть условия задачи. Здесь в подавляющем большинстве случаев используется небольшой набор стандартных формулировок. Описание входных данных можно заполнять в первую очередь (даже когда не готова легенда).
Если все данные вводятся в одну строку, раздел начинается со слов «Ввод содержит <...>».


Иначе раздел должен иметь соответствующее количество отдельных строк, начинающихся со слов «Первая строка содержит <...>», «Вторая строка содержит <...>» и так далее.
Валидатор и генераторы тестов создаются исключительно по информации в данном разделе (фактически, раздел «Входные данные», код валидатора и код генератора — это три представления одной и той же информации).


Если количество строк определяется некоторым параметром, добавляется фраза «Следующие $N$ строк описывают <...>. Каждая из них содержит <...>» (в отдельных случаях — «$i$-я из них содержит <...>»).
=== Строки входных данных ===


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


=== Описание данных ===
Если есть несколько строк (так чаще всего), то делаем столько же абзацев, каждый начинается с «Первая строка содержит <...>», «Вторая строка содержит <...>» и т. д.
После слова «содержит» указываются типы и имена всех токенов, присутствующих в строке. Количество токенов не указывается.


После имени токена указывается диапазон его значений, при этом все числа, не превышающие 1000, записываются полностью, а превышающие 1000 — в показательной форме.
Если есть блок из N логически объединённых строк: «Следующие $N$ строк описывают <...>. Каждая из них содержит <...>».


Если токены имеют одинаковый тип и связаны по смыслу, у них можно указать общий диапазон значений.
Если есть строка после неопределённого числа строк, то числительное заменяем на «следующая»: «Следующая строка содержит <...>».


После диапазона значений ставится тире и указывается смысл токена. Если строка содержит несколько токенов, то должен быть указан смысл каждого из них (в порядке описания), а в начале или в конце должно присутствовать слово «соответственно».
=== Значения, содержащиеся в строках ===


Для вещественных чисел после диапазона указывается количество дробных знаков («заданное с (не более чем) тремя знаками после десятичной точки»).
Общий вид: «содержит ''тип_значения'' $''имя_значения''$ ($''ограничения''$) --- ''описание_значения''».


Ввод содержит целое число $N$ ($-100 \le N \le 100$) --- счёт Макса.
Если строка содержит несколько значений, то количество НЕ пишется. Неправильно: «Первая строка содержит два целых числа $N$ и $M$». Правильно: «Первая строка содержит целые числа $N$ и $M$».


Третья строка содержит целые числа $A$ и $B$ ($0 \le A, B \le 10^6$) --- количество денег у Макса и Владимира соответственно.
Кроме того, если несколько значений, то раздел описаний (после тире) должен начинаться (предпочтительнее) или заканчиваться словом «соответственно».


Вторая строка содержит целые числа $S$ и $P$ ($1 \le S \le 2$, $30 \le P \le 2 \cdot 10^5$) --- соответственно номер начинающего игрока и силу его персонажа.
Ограничения описываются следующим образом: «($1 \le A \le 10$, $100 \le X \le 200$)». Если несколько значений логически связаны и имеют общие ограничения, их можно объединить: «($1 \le X, Y, Z \le 100$)». Пример с дополнительными ограничениями: «($1 \le H, W \le 300$, $H \cdot W \le 1000$, $H \ne W$)». Обратите внимание, что каждое выражение имеет собственные доллар-скобки.


Первая строка содержит вещественное число $X$ ($0 \le X \le 1$), заданное с 2 знаками после десятичной точки, --- вероятность выигрыша Макса.
Желательно, чтобы порядок описания значений совпадал с порядком в легенде.


Следующие $M$ строк описывают дороги. Каждая из них содержит целые числа $A_i$ и $B_i$ ($1 \le A_i, B_i \le N$) --- номера начального и конечного перекрёстка $i$-й дороги соответственно.
Конкретика по типам:
* Целые числа: «Первая строка содержит целые числа $A$ и $B$ ($1 \le A, B \le 100$) --- соответственно количество зайчиков и количество белочек»
* Вещественные числа: «Первая строка содержит вещественные числа $X$ и $Y$ ($0 \le X, Y \le 1$), заданные с не более чем двумя знаками после десятичной точки, --- соответственно вероятность победы Макса и вероятность победы Владимира.»
* Строки: «Первая строка содержит последовательность $S$ ($10 \le |S| \le 100$), состоящую из строчных латинских букв, пробелов и знаков препинания, --- текст сообщения.»
: Тут есть нюанс. В русском языке слово «строка» обозначает как участок файла, ограниченный \n (row, line), так и последовательность символов (string). Чтобы не писать «строка содержит строку», приходится писать «строка содержит последовательность» или «строка содержит слово» (этот вариант предпочтителен, когда в последовательности нет пробелов или цифр).
* Символы, строки из фиксированного множества: «Первая строка содержит символ $C$ ($C \in \{\texttt{X}, \texttt{Y}, \texttt{Z}\}$) --- тип операции.», «Первая строка содержит слово $T$ ($T \in \{\texttt{PUSH}, \texttt{POP}\}$) --- тип операции.».
 
=== Значения в блоках строк ===
 
Общий вид: «Следующие $N$ строк описывают <...>. Каждая из них содержит <...>.».
 
Количество строк в блоке (N) всегда должно быть описано (определено) до самого блока.
 
К именам значений добавляются индексы: «Следующие $N$ строк описывают картины. Каждая из них содержит целые числа $H_i$ и $W_i$ ($1 \le H_i, W_i \le 100$) --- соответственно высоту и ширину картины.»
 
Если блоков строк несколько, и они логически не связаны, то в первом блоке нужно использовать индексы i, во втором — j, и так далее.
 
Дополнительные ограничения описываются в этом же абзаце: «Следующие $N$ строк описывают названия городов. Каждая из них содержит слово $S_i$ ($10 \le |S_i| \le 20$), состоящее из латинских букв, --- название города. Названия всех городов различны.».


== Раздел «Выходные данные» ==
== Раздел «Выходные данные» ==
Общий вид: Выведите ''количество_значений'' ''тип_значений'' --- ''описание_значений''. Пример: «Выведите одно целое число --- максимально возможную зарплату Макса».
Нельзя писать «Выведите одно целое число --- ответ на задачу», это выдаёт в вас лентяя и импотента. Нужно кратко, но явно повторить, какое именно значение ожидается.
Если значений несколько, то после тире появляется слово «соответственно»: «Выведите два целых числа --- соответственно минимальную и максимальную зарплату Макса».
Если выводятся вещественные числа, требуется указание на точность: «Точность ответа должна составлять не менее 4 знаков после десятичной точки». (Вообще говоря, правильно писать «Абсолютная или относительная погрешность ответа должна составлять не более 10^{-4}», но школьники этого не поймут).
Если ответ нужно выводить по модулю: «Так как ответ может оказаться очень большим, выведите остаток от его деления на 1000000007».
Если возможны несколько ответов: «Если подходящих ответов несколько, выведите любой из них». Вместо «ответов» можно конкретизировать: «чисел», «последовательностей» и т. д.
Если возможно отсутствие ответа: «Если Макс не сможет составить набор, выведите -1».
Если выводится сложный ответ с количеством строк в начале: «В первой строке выведите целое число $K$ --- количество ходов Макса. В каждой из следующих $K$ строк выведите одно целое число --- номер хода.»
Если количество значений или строк в ответе заранее не известно: «Выведите одно или более целых чисел --- бонусы Макса».
== Прочие замечания по оформлению ==
Знаки:
* Тире: ---
* Меньше или равно: \le
* Больше или равно: \ge
* Не равно: \ne
* Принадлежит: \in
* Оператор «точка»: \cdot
* Оператор «крестик»: \times («Поле имеет размер $H \times W$»)
Маркированный список (нумерованный — точно так же, но с «enumerate» вместо «itemize»):
\begin(itemize)
\item Первый элемент
\item Второй элемент
\end{itemize}
Строковые константы, особенно которые нужно выводить, выделяются моноширинным шрифтом: «Выведите \t{YES}, если Макс выиграет. В противном случае выведите \t{NO}».
Степени десятки: 10, 100 и 1000 пишутся полностью, дальше — в показательной форме: 10^4, 10^5 и т. д.
== Валидатор ==
Все числовые константы начиная с 1e4 пишем в экспоненциальном виде: не 2000000000, а (int)2e9. Никто не будет считать эти ваши нули, избавьте нас от этого.
Если в цикле считывается много однотипных значений, добавляйте индексы: пишите не просто inf.readInt(1, 100, "a"), а так: inf.readInt(1, 100, format("a[%d]", i)). Если проблема будет в одном из тысячи чисел, вы будете знать, в каком именно.

Текущая версия от 19:07, 7 февраля 2022

Раздел «Входные данные»

Описание формата входных данных — самая формализованная часть условия задачи. Здесь в подавляющем большинстве случаев используется небольшой набор стандартных формулировок. Описание входных данных можно заполнять в первую очередь (даже когда не готова легенда).

Валидатор и генераторы тестов создаются исключительно по информации в данном разделе (фактически, раздел «Входные данные», код валидатора и код генератора — это три представления одной и той же информации).

Строки входных данных

Если все входные данные даны в одну строку, то пишем «Ввод содержит <...>».

Если есть несколько строк (так чаще всего), то делаем столько же абзацев, каждый начинается с «Первая строка содержит <...>», «Вторая строка содержит <...>» и т. д.

Если есть блок из N логически объединённых строк: «Следующие $N$ строк описывают <...>. Каждая из них содержит <...>».

Если есть строка после неопределённого числа строк, то числительное заменяем на «следующая»: «Следующая строка содержит <...>».

Значения, содержащиеся в строках

Общий вид: «содержит тип_значения $имя_значения$ ($ограничения$) --- описание_значения».

Если строка содержит несколько значений, то количество НЕ пишется. Неправильно: «Первая строка содержит два целых числа $N$ и $M$». Правильно: «Первая строка содержит целые числа $N$ и $M$».

Кроме того, если несколько значений, то раздел описаний (после тире) должен начинаться (предпочтительнее) или заканчиваться словом «соответственно».

Ограничения описываются следующим образом: «($1 \le A \le 10$, $100 \le X \le 200$)». Если несколько значений логически связаны и имеют общие ограничения, их можно объединить: «($1 \le X, Y, Z \le 100$)». Пример с дополнительными ограничениями: «($1 \le H, W \le 300$, $H \cdot W \le 1000$, $H \ne W$)». Обратите внимание, что каждое выражение имеет собственные доллар-скобки.

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

Конкретика по типам:

  • Целые числа: «Первая строка содержит целые числа $A$ и $B$ ($1 \le A, B \le 100$) --- соответственно количество зайчиков и количество белочек»
  • Вещественные числа: «Первая строка содержит вещественные числа $X$ и $Y$ ($0 \le X, Y \le 1$), заданные с не более чем двумя знаками после десятичной точки, --- соответственно вероятность победы Макса и вероятность победы Владимира.»
  • Строки: «Первая строка содержит последовательность $S$ ($10 \le |S| \le 100$), состоящую из строчных латинских букв, пробелов и знаков препинания, --- текст сообщения.»
Тут есть нюанс. В русском языке слово «строка» обозначает как участок файла, ограниченный \n (row, line), так и последовательность символов (string). Чтобы не писать «строка содержит строку», приходится писать «строка содержит последовательность» или «строка содержит слово» (этот вариант предпочтителен, когда в последовательности нет пробелов или цифр).
  • Символы, строки из фиксированного множества: «Первая строка содержит символ $C$ ($C \in \{\texttt{X}, \texttt{Y}, \texttt{Z}\}$) --- тип операции.», «Первая строка содержит слово $T$ ($T \in \{\texttt{PUSH}, \texttt{POP}\}$) --- тип операции.».

Значения в блоках строк

Общий вид: «Следующие $N$ строк описывают <...>. Каждая из них содержит <...>.».

Количество строк в блоке (N) всегда должно быть описано (определено) до самого блока.

К именам значений добавляются индексы: «Следующие $N$ строк описывают картины. Каждая из них содержит целые числа $H_i$ и $W_i$ ($1 \le H_i, W_i \le 100$) --- соответственно высоту и ширину картины.»

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

Дополнительные ограничения описываются в этом же абзаце: «Следующие $N$ строк описывают названия городов. Каждая из них содержит слово $S_i$ ($10 \le |S_i| \le 20$), состоящее из латинских букв, --- название города. Названия всех городов различны.».

Раздел «Выходные данные»

Общий вид: Выведите количество_значений тип_значений --- описание_значений. Пример: «Выведите одно целое число --- максимально возможную зарплату Макса».

Нельзя писать «Выведите одно целое число --- ответ на задачу», это выдаёт в вас лентяя и импотента. Нужно кратко, но явно повторить, какое именно значение ожидается.

Если значений несколько, то после тире появляется слово «соответственно»: «Выведите два целых числа --- соответственно минимальную и максимальную зарплату Макса».

Если выводятся вещественные числа, требуется указание на точность: «Точность ответа должна составлять не менее 4 знаков после десятичной точки». (Вообще говоря, правильно писать «Абсолютная или относительная погрешность ответа должна составлять не более 10^{-4}», но школьники этого не поймут).

Если ответ нужно выводить по модулю: «Так как ответ может оказаться очень большим, выведите остаток от его деления на 1000000007».

Если возможны несколько ответов: «Если подходящих ответов несколько, выведите любой из них». Вместо «ответов» можно конкретизировать: «чисел», «последовательностей» и т. д.

Если возможно отсутствие ответа: «Если Макс не сможет составить набор, выведите -1».

Если выводится сложный ответ с количеством строк в начале: «В первой строке выведите целое число $K$ --- количество ходов Макса. В каждой из следующих $K$ строк выведите одно целое число --- номер хода.»

Если количество значений или строк в ответе заранее не известно: «Выведите одно или более целых чисел --- бонусы Макса».

Прочие замечания по оформлению

Знаки:

  • Тире: ---
  • Меньше или равно: \le
  • Больше или равно: \ge
  • Не равно: \ne
  • Принадлежит: \in
  • Оператор «точка»: \cdot
  • Оператор «крестик»: \times («Поле имеет размер $H \times W$»)

Маркированный список (нумерованный — точно так же, но с «enumerate» вместо «itemize»):

\begin(itemize)
\item Первый элемент
\item Второй элемент
\end{itemize}

Строковые константы, особенно которые нужно выводить, выделяются моноширинным шрифтом: «Выведите \t{YES}, если Макс выиграет. В противном случае выведите \t{NO}».

Степени десятки: 10, 100 и 1000 пишутся полностью, дальше — в показательной форме: 10^4, 10^5 и т. д.

Валидатор

Все числовые константы начиная с 1e4 пишем в экспоненциальном виде: не 2000000000, а (int)2e9. Никто не будет считать эти ваши нули, избавьте нас от этого.

Если в цикле считывается много однотипных значений, добавляйте индексы: пишите не просто inf.readInt(1, 100, "a"), а так: inf.readInt(1, 100, format("a[%d]", i)). Если проблема будет в одном из тысячи чисел, вы будете знать, в каком именно.