Вас вітає Алготестер!
Що таке Алготестер?
Система автоматичного тестування розв’язків з великим набором цікавих алгоритмічних задач різноманітної складності.
Платформа для підготовки задач.
Платформа для проведення змагань з олімпіадного програмування за правилами ICPC та IOI.
Платформа для проведення оптимізаційних змагань.
Що потрібно зробити, щоб почати користуватись Алготестером?
Для початку роботи з Aлготестером потрібно пройти швидку реєстрацію. Для цього перейдіть на сторінку реєстрації за допомогою кнопки у правому верхньому куті. У полі "Ім’я користувача" потрібно ввести унікальне ім’я користувача за яким Вас буде ідентифікувати система. Воно повинно:
Бути унікальним.
Мати довжину від 4 до 47 символів.
Містити великі та малі латинські літери, цифри, крапку та нижнє підкреслення.
Починатися з букви.
У полях "Ім’я" та "Прізвище" введіть свої справжні ім’я та прізвище. У полі "Електронна скринька" введіть Вашу електронну скриньку. Ви повинні мати доступ до неї для підтвердження облікового запису. У полі "Пароль" введіть свій пароль, який використовуватимете для входу в систему. Пароль повинен мати від 4 до 47 символів, та бути надійним. Продублюйте ваш пароль у полі "Підтвердження пароля". Погодьтеся з умовами та правилами використання платформи Алготестер.
Після заповнення форми, зайдіть на свою електронну пошту та очікуйте на лист підтвердження облікового запису. Підтвердіть ваш облікового запису.
Я хочу спробувати розв’язати одну дуже просту задачу і, якщо сподобається, то більше.
Повний список задач в архіві можна знайти в секції Задачі в лівому меню.
Найпростіша задача архіву — задача A плюс B. Нижче наведені приклади кодів для її розв’язання використовуючи всі доступні мови програмування.
Для того щоб надіслати розв’язок потрібно вибрати спосіб надсилання коду (файл чи вихідний код) та компілятор. В залежності від способу надсилання потрібно прикріпити файл або вставити вихідний код Вашої програми у відповідне поле, та натиснути "Надіслати".
У табличці нижче будуть доступні всі розв’язки, які були надіслані Вами по вибраній задачі, а також результат виконання кожного з них. Ви можете детально подивитися на кожну свою спробу. Ви можете бачити надісланий код, вивід компілятора та результат виконання кожного тесту. Тестування відбувається до першого не пройденого тесту.
У вкладці "Успішні розв’язки" Ви можете бачити список всіх користувачів, які розв’язали дану задачу, та результат виконання їхнього коду.
Я отримав результат "Неправильна відповідь" на задачі "A плюс B".
Це означає, що ваш розв’язок є наразі неправильним і на деяких вхідних даних, які дозволені згідно з умовою, Ваша програма повертає неправильну відповідь до задачі. Ось список усіх можливих вердиктів:
Неправильна відповідь На деяких вхідних даних, які дозволені згідно з умовою, ваша програма повертає неправильну відповідь до задачі. Помилка часу виконання Програма неочікувано завершила роботу (наприклад була спроба поділити на 0, або індексувати за межами масиву). Перевищено ліміт часу Програма працює на одному тесті повільніше, ніж ліміт, зазначений в умові задачі. Перевищено ліміт пам’яті Програма використовує на одному тесті більше оперативної пам’яті, ніж зазначено в умові задачі. Помилка компілювання Компілятор видав помилку при компіляції Вашого вихідного коду. Для того, щоб побачити вивід помилки компілятора перейдіть в перегляд розв’язку у вкладку Компілятор. Внутрішня помилка Помилка в системі тестування і розпорядники платформи працюють над її усуненням. Ліміт часу очікування Інтерактор занадто довго очікує на вивід програми. Ця помилка виникає при порушенні протоколу взаємодії. Зараховано Це єдиний вердикт який хороший для вас — Ваша задача повністю правильна і пройшла всі тести! Де знайти задачі?
У секції Задачі є можливість є можливість:
Впорядкувати задачі за кількість учасників, які її здали. Прості задачі здають частіше ніж складні.
Вибрати тему чи складність задачі за допомогою міток. Натисніть на мітку, або впишіть тему у поле пошуку.
Знайти якусь конкретну задачу за її номером, назвою, або джерелом (назва змагання у якому задача була використана).
Де шукати підказки, якщо в мене не виходить зробити задачу?
У секції Розбір є письмові розбори до деяких задач. Також на нашому ютуб-каналі ви зможете знайти відеорозбори до частини задач.
Чи можу я порівняти свої успіхи в розв’язуванні задач з успіхами інших учасників?
Так, в секції Рейтинг лівого меню доступний повний список учасників, посортований за кількістю розв’язаних задач. Також, в секції Черга розв’язків доступна онлайн черга, в якій показано результати перевірки надісланих Вами та іншими учасниками розв’язків.
Архів це круто, але чи можу я взяти участь у реальному змаганні?
В ЛНУ ім. І. Франка (а також інших університетах Львова), використовуючи платформу Алготестер, регулярно проводять змагання, участь в яких можна приймати онсайт разом з іншими командами. Підписуйтеся на наші сторінки у Facebook, Twitter та Telegram , щоб не пропустити жодної події.
Які мови програмування можна використовувати для розв’язання задач?
Мова Версія Параметри компіляції C++ g++ 6.4.0 -O2
C++ 17 g++ 10.3.1 -O2 -std=c++17
C# Mono C# compiler version 6.4.0.0 /o+ /r:System.Numerics.dll
Java openjdk 1.8.0 Pascal Free Pascal Compiler 3.0.4 -O2 -Sh
Python Python 3.8.1 -O
PyPy PyPy 7.3.0 with GCC 9.2.0 -O
F# F# Compiler 4.0 -r:System.Numerics.dll --optimize+ --crossoptimize+
Go Go 1.20.5 Node.js Node.js 20.0.0 Ruby Ruby 3.2.2 Rust Rust 1.70 -C opt-level=3
Приклади розв’язку задачі "A плюс B" різними мовами програмування:
C++ / C++ 17
C#
Java
Pascal
Python 3 / PyPy
F#
let main() = let line = System.Console.ReadLine() let numbers = line.Split(' ') let a = System.Int32.Parse(numbers.[0]) let b = System.Int32.Parse(numbers.[1]) System.Console.WriteLine(a + b) main()
Go
Node.js
function Main(input) { s = input.split(" "); var a = parseInt(s[0]); var b = parseInt(s[1]); console.log('%d', a+b); } Main(require("fs").readFileSync("/dev/stdin", "utf8"));
Ruby
Rust
use std::io; fn main() { // Read input from stdin let mut input = String::new(); io::stdin() .read_line(&mut input) .expect("Failed to read input."); // Parse input string to numbers let mut numbers = input.split_whitespace(); let a: i32 = numbers.next().unwrap().parse().expect("Invalid number entered for a."); let b: i32 = numbers.next().unwrap().parse().expect("Invalid number entered for b."); // Calculate the sum let sum = a + b; // Write the sum to stdout println!("{}", sum); }
Процес додавання задач у платформу Алготестер
У правому верхньому куті сайту відкрийте вкладку «Задачі (Автор)». У цій секції відображаються всі створені Вами задачі, а також ті задачі, автор яких вказав Вас помічником. Також Ви побачите 5 кнопок: «Створити», «Видалити», «Змінити порядок», «Перетестувати» та «Надіслати».
Натисніть кнопку «Створити». Ви побачите вкладку зі створення задачі. Необхідно зразу вказати 4 обов’язкові поля для створення задачі: «Назва», «Час (сек.)», «Пам’ять (МіБ)» та «Вивід (МіБ)». У полі «Назва» вкажіть назву задачі. Вимоги до назви:
Не використовуйте спеціальні символи (
$&*%
)Назва не повинна бути довгою (не більше семи слів)
Назва повинна бути унікальною. У архіві не повинно бути задач з такою назвою.
Зауважте, що в умові задачі буде та назва, яку Ви вкажете при створенні умови. У полі «Час (сек.)» введіть максимальний час виконання одного тесту у секундах. Стандартне обмеження на час 2 секунди. Обмеження на час повинно бути до 7 секунд.
У полі «Пам’ять (МіБ)» введіть обмеження на використання оперативної пам’яті для одного тесту. Стандартне обмеження на пам’ять 256 Мебібайт. Обмеження на пам’ять повинно бути від 128 Мебібайт до 1024 Мебібайт. Обмеження на пам’ять повинно бути степенем двійки.
Якщо обмеження на час або пам’ять є меншими за стандартні, то переконайтеся що задача розв’язна на Python та Java.
У полі «Вивід (МіБ)» введіть максимальний розмір виводу програми на одному тесті. Стандартне значення виводу 1 Мебібайт.
Обмеження до задачі потрібно вибирати так, щоб вони були хоча б у 2 рази більшими, ніж потребує авторський розв’язок.
Всі інші поля можна буде заповнити пізніше.
Після створення задачі Ви повернетеся до вкладки «Задачі (Автор)». Там буде новостворена вами задача. Натиснувши на назву задачі, Ви перейдете на сторінку налаштувань.
На сторінці налаштування задачі Ви побачите 9 вкладок:
У домашній вкладці (позначається хаткою) Ви можете змінювати обмеження на час та пам’ять, змінювати назву, вибирати першоджерела та ін. Після написання першоджерел, необхідно вибрати їх у цій вкладці. Достовірник (checker) до задачі, можна вибрати одразу.
У вкладці «Помічники» Ви можете додавати помічників до задачі. Ви можете вибрати помічника та присвоїти йому роль яку він буде виконувати при підготовці цієї задачі.
У вкладці «Умови» Ви можете створювати умови українською та англійською мовами. Детальніше про створення умов читайте в пункті «Умови».
У вкладці «Ресурси» Ви можете додавати ресурси до задачі, наприклад картинки до умови.
У вкладці «Першоджерела» Ви можете створювати генератори (generator), перевірники (validator), достовірники (checker), оцінювачі (scorer) та розв’язки. Детальніше про кожен тип Ви зможете прочитати у відповідному пункті наступного розділу.
У вкладці «Тести» Ви можете створювати ручні тести, створювати тести за допомогою генератора або додавати архіви тестів. При створенні тестів вам необхідно вказати їхню назву, вартість та самі тести (в разі створення ручних тестів), або параметри генератора. Якщо Ви хочете зробити цей тест прикладом, який буде відображений в умові, то Вам потрібно поставити прапорець у чекбоксі «приклад». Детальніше про створення тестів генератором читайте у розділі генератор. Детальніше про вартість тестів читайте в пункті «Оцінювач».
У вкладці «Мітки» Ви можете вказувати мітки до задачі.
У вкладці «Результат», після надсилання задачі, Ви можете переглядати створені вами тести, та результат роботи вашого розв’язку.
У вкладці «Розв’язки користувачів» Ви можете переглядати всі розв’язки інших користувачів.
Справа від вкладок будуть 2 кнопки: «Змінити» та «Надіслати».
Етапи створення задач
Умова
Першим кроком створення задачі є створення умови. Умова є обов’язковою частиною задачі. У вкладці «Умова» Ви побачите три кнопки: «Створити», «Видалити» та «Надіслати». Щоб створити умову натисніть на кнопку «Створити».
Умова — дуже важлива частина задачі, де Ви повинні доступно пояснити суть задачі. Умови на Алготестері пишуть мовою розмітки даних LaTeX. При створенні умови Ви побачите 6 вкладок:
У домашній вкладці (позначається хаткою) Ви можете вибрати мову та змінювати назву задачі.
У вкладці «Опис» Ви повинні описати суть задачі, розказати що дано, пояснити що потрібно зробити користувачеві, щоб її здати.
У вкладці «Вхідні дані» Ви повинні описати які дані користувач отримає та в якому порядку та форматі їх задано.
У вкладці «Вихідні дані» Ви повинні описати яку відповідь очікуєте від користувача та у якому форматі він має її вивести.
У вкладці «Обмеження» Ви повинні дати обмеження на всі вхідні дані. Якщо в умові ви гарантували якісь спеціальні обмеження, наприклад відсутність петель чи мультиребер у графі, їх варто згадати й тут.
У вкладці «Примітки» Ви можете пояснити приклади, написати важливе зауваження, яке може бути не очевидним в описі, або ж уточнити деталі які допоможуть користувачеві зрозуміти що саме йому потрібно зробити.
Дотримуйтеся наших рекомендацій щодо написання умов. Після написання умови, для того щоб її згенерувати необхідно натиснути на кнопку «Надіслати». Приклади умов Ви можете знайти в архіві задач.
Розв’язок
Наступним кроком є написання розв’язку до задачі. Розв’язок задачі — це вихідний код, який система буде компілювати та виконувати на наборі тестів, для звірення відповіді з відповідями учасників. У задачі повинен бути один основний розв’язок. Розв’язок повинен зчитувати вхідні дані у форматі, описаному в умові. Вказати основний розв’язок для задачі можна на домашній вкладці (позначається хаткою). Рекомендуємо, щоб кожна задача мала ще й інші розв’язки, написані тестерами, аби уникнути помилок в основному.
Ознайомлення з бібліотеками
Ознайомитися з нашою бібліотекою Ви можете в цій статті. Приклади використання є в наступних пунктах.
Перевірник
Наступною обов’язковою складовою задачі є перевірник. Перевірник (Validator) — програма яка зчитує один тест і перевіряє чи він відповідає формату й обмеженням, що зазначені в умові. Використовуйте нашу бібліотеку при написанні перевірників до задач. Перевірник зчитує вхідні дані зі стандартного потоку вводу (
STDIN
), та виводить у стандартний потік виводу(STDOUT
). Якщо перевірник виявляє некоректний тест, то він повинен вивести короткий текст-пояснення помилки та повернути 0. Тест вважається коректним якщо перевірник нічого не вивів і повернув 0. Перевірники повинні перевіряти не лише обмеження на розмір вхідних даних, елементів масиву, а й зв’язність графа, відсутність циклів у ньому чи будь-які інші гарантовані умови й обмеження. У задачі повинен бути один основний перевірник. Вказати основний перевірник для задачі потрібно на домашній вкладці (позначається хаткою). Ось декілька прикладів перевірників: перевірник до задачі A плюс B, перевірник до задачі Марічка і печиво, перевірник до задачі Коля, Вася і лабіринт.Звичайний достовірник
Останнім обов’язковим пунктом створення задач є достовірник. Достовірник (Checker) — програма яка перевіряє правильність відповіді. Якщо відповідь до задачі однозначна — то для цього існує
Token Checker
. Якщо ж потрібно перевірити відповідь у дійсних числах, використовуйтеDouble Checker
з потрібною для вас точністю. Якщо до задачі немає єдиної відповіді, то потрібно написати достовірник самостійно. Використовуйте нашу бібліотеку при написанні достовірників до задач. Використовуйте функцію «initChecker». Вона повертає масив з трьох елементів: читач тестових даних, читач виводу користувача та читач виводу авторського розв’язку. Якщо відповідь користувача є неправильною, то достовірник повинен вивести помилку та повернути 0. Відповідь вважається правильною якщо достовірник нічого не вивів і повернув 0. Достовірник приймає 4 параметри: шляхи до файлів з вхідними даними, виводом користувача, авторським виводом, кодом користувача. У задачі повинен бути один основний достовірник. Вказати основний достовірник для задачі можна на домашній вкладці(позначається хаткою). Ось декілька прикладів достовірників: Token Checker, Double Checker 1e-4, достовірник до задачі Подвоєна сума квадратів, достовірник до задачі Марічка і смачні цукерки.Тести
На цьому етапі ваша задача вже має всі необхідні компоненти. Ви можете повернутися до домашньої вкладки (позначається хаткою), вибрати всі першоджерела до задачі та надіслати її. Якщо Ви все зробили правильно, то задача отримає статус «Успішно завершено».
Попри те, що задача збудувалася, в ній поки немає тестів. Тести — це набори вхідних даних, на яких будуть перевірятися розв’язки користувачів. Є три способи додати тест до задачі:
Створити ручний тест. Ручний тест — це тест, який задається вручну. Такі тести можна роботи прикладами, які відображатимуться в умові.
Написати генератор тестів (детальніше в наступному пункті).
Додати архівні тести. Щоб додати архівні тести, потрібно надіслати архів у форматі Zip, та вказати розширення вхідних та вихідних файлів. Всі файли зі вхідними та вихідними даними повинні мати відповідні розширення до тих, які Ви вказали. Файли з вхідними та вихідними даними, які стосуються одного тесту повинні мати однакову назву.
Генератор
Генератор — програма яка дозволяє автоматизувати процес генерації тестів. Використовуйте нашу бібліотеку при написанні генераторів до задач. Генератору можна передавати параметри, наприклад максимальний розмір тесту чи обмеження параметрів задачі. Першим параметром (з індексом 1) завжди передається номер тесту. Наступні параметри Ви повинні вказати самостійно. Останнім параметром ви можете додати міш. Це випадково згенерований рядок. Його потрібно додавати, щоб неможливо було відновити тести, маючи код генератора. Генератор псевдовипадкових чисел ініціалізовується від усіх параметрів. Генератор повинен виводити результат у стандартний потік виводу(
STDOUT
).Ось декілька прикладів генераторів: генератор до задачі A плюс B, генератор до задачі Марічка і печиво.
В однієї задачі може бути декілька генераторів, які генерують різні типи вхідних даних. Ось один приклад та інший приклад генератора до задачі Максим, Петро й Богдан. Перший генератор формує випадковий зв’язний граф, а другий граф зірку заданого розміру. Оскільки це 2 різні типи графів, то довелося використати більш ніж 1 генератор.
Надсилання задачі
Після написання всіх першоджерел і додавання тестів задачу потрібно надіслати. Щоб надіслати задачу натисніть на кнопку «Надіслати», що знаходиться справа від вкладок налаштування задачі. Після надсилання задачі відбудеться наступне:
Сформуються тести. Генератор (Generator) згенерує тести, і разом з ручними та архівними тестами, сформується набір тестів.
Перевірник (Validator) перевірить тести на коректність.
Розв’язок (Solution) запуститься на наборі тестів, і будуть сформовані авторські відповіді.
Якщо на будь-якому з цих етапів виникне помилка, то задача отримає статус Містить помилки, і у вкладці «Результат» буде вказано що саме пішло не так. У іншому випадку у задачі буде статус Успішно завершено. Якщо у задачі є статус Успішно завершено, то Ви зможете побачити тести у вкладці «Результат».
Інтерактивний достовірник
Інтерактивний достовірник — це достовірник для інтерактивних задач. Використовуйте функцію «initInteractiveChecker». Вона повертає масив з трьох елементів: читач тестових даних, потік вводу користувача (Вам потрібно писати вхідну інформацію в цей потік) та читач виводу користувача (зчитуйте відповіді користувача з нього).
Генератор та перевірник до інтерактивних задач повинні генерувати та перевіряти лише вхідні дані для достовірника, але не для розв’язків задачі. Розв’язки задачі взаємодіють лише з інтерактивним достовірником. Зауважте, інтерактивний достовірник відповідає не лише за перевірку правильності розв’язку, а й за надання користувачеві вхідної інформації. Ось приклад інтерактивного достовірника до задачі Інтерактивне число. Приклади перевірника та генератора до неї: перевірник до задачі та генератор до задачі.
Оцінювачі та вартість тестів
Якщо для задачі Ви хочете також враховувати частково правильні розв’язки, то ви можете нараховувати бали за них. Тоді користувач зможе набрати певну частину балів за задачу, якщо не придумав достатньо швидкий чи абсолютно правильний розв’язок. Найпростіший спосіб це зробити поставивши кожній групі тестів певну вартість. Бали за групу тестів користувач отримає лише якщо його розв’язок буде правильним для всіх тестів з групи.
Отримати певну кількість балів за задачу також можна за допомогою оцінювача. Перед отримуванням балів за розв’язок, його перевіряє достовірник. Оцінювач оцінює лише ті розв’язки, які пройшли перевірку достовірника. Оцінювач приймає 6 параметрів, що є шляхами до файлів:
Файл з вхідними даними.
Вивід користувача.
Вивід автора.
Тека з обробленими файлами коду (файли STDIN, STDOUT, STDERR, виконуваний файл користувача).
Тека для писання. Це тека для внутрішнього використання оцінювачем. Вона буде очищена між тестами.
Код користувача.
Оцінювач повинен вивести цілу невід’ємну кількість балів які користувач отримає за тест у стандартний потік виводу. Ось приклад оцінювача: оцінювач до задачі Зеник і сортування.
Логи виконання тестів
Щоб побачити результат розв’язку на одному конкретному тесті необхідно:
У вкладці «Першоджерела» для відповідного розв’язку натиснути на «Перегляд», що знаходиться в найправішій колонці «Дії».
Перейти на вкладку «Результат» і подивитися логи відповідного тесту.
Зауважте що дуже великі тести у цій вкладці є неповними, однак ви можете завантажити ZIP архів (у правому верхньому куті) з повними тестами.
Назва задачі
Дотримуйтеся правил вживання великих букв для назв задачі англійською мовою. Приклад: «The Best of the Problems» замість «The best of the problems». Це не застосовується до українських умов.
Уникайте використання спеціальних символів у назві задачі (&\(^\wedge\)@* або схожих).
Назва повинна бути не довгою (до семи слів).
Назва задачі повинна бути унікальною в англійській та українській версіях (Не повинно бути задач в архіві з такою назвою).
Обмеження
Стандартне обмеження на час: 2 с.
Стандартне обмеження на пам’ять: 256МіБ.
Обмеження на час до семи секунд.
Обмеження на пам’ять до 1024Міб, і хоча б 128Міб. Обмеження повинне бути степенем двійки.
Якщо обмеження на час або пам’ять є меншими за стандартні, переконайтеся, що задача є розв’язною на Java та Python.
Абзаци
Відділяйте абзаци пустим рядком в LaTeX; Не використовуйте абзацний відступ або команду
\par
.Умова не повинна бути одним великим абзацом. Розбивайте умову на декілька логічних частин для збільшення читабельності.
Змінні
За замовчуванням, всі змінні в секціях умова та вхідні дані повинні бути в
$
, наприклад:$n$
.Змінні не повинні бути жирними.
Рекомендуємо позначати змінні однією маленькою латинською літерою.
По можливості використовуйте стандартні назви змінних (наприклад \(n\) для кількості вершин, \(m\) для кількості ребер, \(k\) або \(q\) для кількості запитів).
Уникайте використовування змінних індексування (наприклад \(i\) або \(j\)) як назви змінних.
Літерали
Числа не повинні бути в
$
. Приклад: Вершини пронумеровані від 1 до$n$
, включно. Виняток: якщо згідно з умовою потрібно вивести -1 коли відповіді не існує, сприймайте -1 як рядок (дивитися далі).Рядки повинні бути в
\texttt{}
. Наприклад, використовуйте\texttt{YES}
при описі рядкаYES
.Не використовуйте лапки для рядків.
Числа (або змінні) повинні мати правильне закінчення, наприклад: 2-гий, $i$-тий, і т. д.. Те саме і для англійських умов.
Масиви не повинні бути в
$
, наприклад, [4, 7].
Формули
Всі математичні формули повинні бути в
$
, наприклад:$n < m$
.Не використовуйте * для множення. Натомість використовуйте
\cdot
(наприклад$n \cdot m$
).Використовуйте
\times
для опису розмірності матриць. Наприклад матриця розміру$n \times m$
.Не використовуйте знак ділення /. Натомість використовуйте дріб:
$ \frac{a}{b}$
.Використовуйте відповідні команди LaTeX як знаки нерівності:
\le
для ’менше рівне’,\ge
для ’більше рівне’.Великі формули повинні бути в окремому рядку, по центру і в
$$
(подвійний знак долара), наприклад:$$n < m$$
.Використовуйте
^
і_
для верхнього або нижнього індексування, наприклад:$10^9$, $2^{nk}$, $a_i$
.Завжди використовуйте відповідні команди LaTeX для позначення математичних символів. Повний список всіх математичних команд можна знайти тут.
Масиви (окрім літералів) потрібно писати так:
$[a_1, a_2, \ldots, a_n]$
.
Вхідні дані
Завжди зазначайте чи тип вхідних даних (ціле число, дійсне число, рядок чи символ).
Якщо у вхідних даних є дійсні числа, потрібно зрозуміло описати формат в якому вони задаються.
Використовуйте таке формулювання для вхідних даних українською мовою:
У першому рядку задано одне ціле число $n$ — ...., У наступних $n$ рядках задано пари цілих чисел $u_i$ $v_i$, які описують ребра графу...
.Використовуйте таке формулювання для вхідних даних англійською мовою:
The first line of the input contains a pair of integers ..., The following $m$ lines describe..., etc
. Використовуйте правильні англійські артиклі.Не спрощуйте занадто опис вхідних даних. Уникайте
Одне число $n$
. Натомість пишіть:В першому рядку задано одне ціле число $n$ — кількість пляшок
.Кожна змінна повинна бути коротко описаною.
Вихідні дані
Якщо в задачі може не бути відповіді, це повинно бути чітко зазначено в секції вихідні дані.
Якщо в задачі є декілька правильних відповідей, це повинно бути зазначено в секції вихідні дані.
Якщо в задачі можна гарантувати існування відповіді для вхідних даних, це повинно бути зазначено в секції вихідні дані.
Якщо відповідь містить дійсне число, у вихідних даних треба зазначити дозволену похибку (абсолютну і/або відносну).
Якщо відповідь треба вивести за модулем простого числа, це повинно бути зазначено у вихідних даних. Необхідно явно вказати, якщо модуль є простим числом.
Використовуйте таку конструкцію, при описі вихідних даних українською
В єдиному рядку виведіть одне число, що позначає кількість ...
і т. д.Використовуйте таку конструкцію, при описі вихідних даних англійською:
Print a single integer denoting the minimum number ...
etc. Використовуйте правильні англійські артиклі.Не пишіть вихідні дані занадто спрощеними, уникайте
Відповідь на задачу.
Натомість, пишіть:В єдиному рядку виведіть одне ціле число $n$ — кількість пляшок
.
Обмеження
Всі обмеження повинні бути в спеціальній секції умови. Можна повторно зазначати певні обмеження в основній частині для звертання уваги.
Об’єднуйте обмеження коли це доцільно:
$1 \le n, m \le 1000$
.Кожне обмеження має бути в окремому рядку умови (відділене порожнім рядком в LaTeX).
Довжина рядка повинна бути позначена, як |s|.
Використовуйте правильні знаки нерівності (описані в секції формули).
Робіть числа якомога більш зрозумілими. Наприклад, пишіть
$1 \le n \le 2 \cdot 10^9$
замість$1 \le n \le 2000000000$
.Використовуйте круглі або щасливі числа в обмеженнях.
В кінці кожного рядка ставте кому, в кінці останнього — крапку. Будь-яке твердження (окрім першого) має починатися з малої букви.
Списки
Використовуйте відповідні команди LaTeX для списків:
Невпорядкований список: \begin{itemize} \item один елемент списку \item інший елемент списку \end{itemize} впорядкований список: \begin{enumerate} \item один елемент списку \item інший елемент списку \end{enumerate}
Зображення
Всі зображення необхідно завантажити в секцію Ресурси, у задачі.
Посилатися на картинки можна за назвою ресурсу, без розширення файлу.
Зображення необхідно розміщувати по центру, з наступним описом:
\begin{center} \includegraphics[width=0.5\textwidth]{resource-name} \end{center}
Приклади
Умова повинна містити хоча б один приклад.
Уникайте використання занадто простих прикладів (ака приклади Бойка).
Перший приклад повинен бути першим тестом у задачі. Те саме стосується й інших прикладів, якщо вони є.
Примітки
У примітках необхідно пояснити приклад, якщо це доцільно.
У примітки можна додавати додаткові означення, якщо це необхідно, проте необхідно посилатися на них в основній частині умови.
Різне
Частини умови, які необхідно виділити (неочевидні обмеження або умови, виправлені частини умови, і т. д.) повинні бути жирними (написаними в
\textbf{}
).Використовуйте
---
і українських і--
в англійських умовах. Ніколи не використовуйте - як тире.Використовуйте перевірники орфографії при написанні українських чи англійських умов.
Бібліотеки algotester.h та algotester_generator.h створені для полегшення написання першоджерел до задач. Використовуйте їх при написанні всіх перевірників, достовірників, оцінювачів та генераторів тестів.
Бібліотека algotester.h
Під час використання бібліотеки Ви працюватимете з класом
AlgotesterReader
. Це клас для зчитування даних. При
зчитуванні він також може перевіряти різні властивості. Цей зчитувач
працює у двох режимах: строгий для перевірників та нестрогий для
достовірників й оцінювачів. У строгому режимі потрібно перевіряти формат
даних включно з пробілами та символами кінця рядка. У нестрогому окремо
зчитувати пробіли чи символи кінця рядка непотрібно.
Список методів класу AlgotesterReader
та їх короткий
опис:
readChar
— зчитує один символ. В нього можна передати список можливих значень, чи нехтувати пробільними символами (не можна в строгому режимі) та назву змінної яку зчитуємо. Повертає символ, який зчитали, або видає помилку, якщо щось пішло не так. Якщо символ може приймати довільні значення, то як список можливих треба передати порожній рядок.readSpace
— зчитує один пробіл. Потрібно робити в строгому режимі.readEndl
— зчитує символ кінця рядка. Потрібно робити в строгому режимі.readEof
— зчитує символ кінця файлу. Потрібно завжди робити у перевірнику та достовірнику з потоку користувача, щоб переконатися у відсутності зайвого виводу.isEof
— перевіряє чи вже кінець файлу. Приймає параметр чи нехтувати пробільними символами (не можна в строгому режимі). Якщо нехтувати пробільними символами, то повертаєtrue
, якщо залишилися лише пробільні символи.readInt
— повертає ціле 64-бітне число. Може приймати параметри нижню та верхню межі включно та назву змінної яку зчитуємо. Наприкладint n = reader.readInt(2, 100000, "n");
зчитає змінну \(n\), та перевірить чи вона є в межах від 2 до \(10^5\).readVectorInt
— повертає вектор цілих 64-бітних чисел. Приймає розмір вектора. Можна вказати межі в яких повинні бути всі елементи вектора включно та назву змінної. Наприкладvector<int> a = reader.readVectorInt(5, 1, 100, "a");
зчитає вектор з 5 елементів між 1 і 100. У строгому режимі всі значення повинні бути задані через пробіл та закінчуватися на символ кінця рядка, без зайвого пробілу після останнього символа.readUInt
— те саме, що йreadInt
, але працює з беззнаковими (невід’ємними) числами.readToken
— зчитує рядок. Може приймати назву змінної та регулярний вираз. Також можна задати мінімальну та максимальну довжину. Декілька прикладів:string s = reader.readToken(1, 1e5, "s", "(0|1)*");
— зчитує бінарний рядок (кожен символ 0 або 1), перевіряє чи його довжина між 1 і \(10^5\).string s = reader.readToken("s", "[a-z]+");
— зчитує рядок довільної довжини та перевіряє чи кожен символ це мала латинська буква.Якщо є обмеження на розмір, то їх необхідно писати як додаткові параметри функції, а не як частину регулярного виразу.
readLine
— зчитує рядок до символу нового рядка.readDouble
— зчитує дійсне число. Можливі параметри: мінімальне значення, максимальне значення, мінімальна кількість цифр після коми, максимальна кількість цифр після коми, чи можна зчитувати у форматі експоненти та назва змінної. Порівняння на межі виконуються явно, тому при передачі меж враховуйте похибку дійсних чисел.
Детальніше прочитати про ці методи можна тут.
Інші важливі функції бібліотеки:
initValidator
— повертає зчитувач в строгому режимі для перевірника. Використовувати для перевірників. Не приймає нічого.initChecker
— повертає масив з трьох зчитувачів у нестрогому режимі: зчитувача з потоку вхідних даних, зчитувача з потоку відповіді користувача та зчитувача з потоку відповіді автора. Використовувати для достовірників. Приймає вхідні параметри програми (int argc, char* argv[]).initInteractiveChecker
— повертає кортеж з таких елементів: зчитувач вхідних даних, потік для зчитування користувача (в нього потрібно виводити відповіді користувачу) та зчитувач з потоку виводу користувача. Використовувати для інтерактивних достовірників. Приймає вхідні параметри програми (int argc, char* argv[]).initScorer
— повертає масив з трьох зчитувачів у нестрогому режимі: зчитувача з потоку вхідних даних, зчитувача з потоку відповіді користувача та зчитувача з потоку відповіді автора. Використовувати для оцінювачів. Приймає вхідні параметри програми (int argc, char* argv[]).isClose
— перевіряє чи дійсні числа є близькими. Приймає два дійсних числа, абсолютну та відносну похибки. Похибки за замовчуванням рівні \(10^{-7}\).equalsIgnoreCase
— перевіряє чи рядки однакові, ігноруючи регістр.check
— приймає умову і рядок (помилку в разі невиконання умови). Якщо умова не виконується виводить рядок.
Приклади написання перевірників, достовірників та інших першоджерел можна знайти тут.
Бібліотека algotester_generator.h
Ця бібліотека створена для полегшення написання генераторів до задач.
Вона містить в собі клас AlgotesterGenerator
. Для роботи з
нею Вам потрібно ініціалізувати генератор функцією
initGenerator
. Вона приймає параметри, які отримує Ваша
програма при запуску. Це можна зробити так:
auto gen = initGenerator(argc, argv)
. При створенні тестів
генератором рекомендуємо завжди ставити відмітку в полі «Додавати міш до
аргументів». Після цього Ви зможете використовувати методи для
генерування різних величин.
Список методів класу AlgotesterGenerator
та їх короткий
опис:
randInt
— повертає випадкове, рівномірно розподілене, ціле 64-бітне число. В цей метод ще можна передати межі. Якщо передати одне число \(n\), то згенероване число буде з проміжку \([0, n)\). Якщо ж передати два числа \(l\) та \(r\) — то з проміжку \([l, r]\).randUInt
— те саме, що йrandInt
, але генерує беззнакові (невід’ємні) числа.randDouble
— повертає випадкове, рівномірно розподілене, дійсне число з проміжку \([0, 1]\). Якщо передати одне число \(n\), то згенероване число буде з проміжку \([0, n]\). Якщо ж передати два числа \(l\) та \(r\) — то з проміжку \([l, r]\).shuffle
— змінює порядок елементів на випадковий. Може приймати вектор, або ітератори на початок та кінець.randomElement
— повертає випадковий елемент вектора.randLogUniform
— приймає ціле число \(n\), повертає випадкове число з проміжку \([1, n]\), таке що логарифм числа є рівномірно розподіленою величиною. Це може бути корисно, якщо Ви хочете генерувати як великі, так і малі тести.randBiasedInt
— приймає межі та \(t\). Якщо лише одна межа \(n\), то генерує число в проміжку \([0, n)\). Якщо ж дві межі \(l\) та \(r\), то з проміжку \([l, r]\). Генерує \(|t| + 1\) число. Якщо \(t = 0\), то повертає випадкове число, якщо \(t < 0\), то повертає найменше зі згенерованих, якщо \(t > 0\) — найбільше. Працює за O(1).getArg
— приймає індекс \(i\), повертає \(i\)-тий аргумент із вхідних параметрів.
Повний опис всіх методів можна знайти тут.