Розбір завдань відбіркового раунду RCC 2016



Завершився черговий — відбірковий — раунд міжнародного чемпіонату програмістів Russian Code Cup 2016. І, за традицією, ми пропонуємо вам ознайомитися з рішеннями завдань, які пропонувалися конкурсантам в останньому раунді. На цей раз завдань було шість, хоча на їх рішення, як і раніше виділялося дві години. За вихід у наступний раунд билося 604 людини. RCC вперше проводиться у тому числі для англомовних учасників. Результат не змусив чекати — російськомовним програмістам буде складена серйозна конкуренція. У фінал пройшло 50 осіб і з них 19 осіб — не російськомовні учасники. Серед фіналістів представники Росії, України, Білорусі, Литви, Словаччини, Вірменії, Польщі, Швейцарії, Фінляндії, Японії, Китаю, Південної Кореї.

  1. Контрольна робота
  2. Багатоніжка
  3. Бінарне дерево
  4. Пробірки і реактиви
  5. Розмін грошей
  6. Завдання F

Завдання А. Контрольна робота
Умова

Обмеження по часу 2 секунди
Обмеження по пам'яті 256 мегабайт

Скоро Колі належить писати важливу контрольну, тому він вирішив ретельно підготуватися. Він з'ясував, що у контрольної буде n варіантів, i-ї з яких складається з mі завдань, пронумерованих від 1 до mі. Для кожного завдання кожного варіанта Коля оцінив час tij хвилин, яке займе у нього рішення.

Під час контрольної він планує вирішувати завдання строго в тому порядку, в якому вони розташовані в варіанті. Здати роботу треба не пізніше закінчення контрольної, яка триває t хвилин. Звичайно, Коля міг би списати контрольну, але він вважає, що це не дуже правильно. Тому готовий списати не більше одного завдання. На списування будь-якого завдання він витратить t0 хвилин.

Тепер, знаючи всю цю інформацію, він хоче для кожного варіанту з'ясувати, скільки завдань він встигне вирішити, якщо йому попадеться цей варіант.

Формат вхідних даних

У першому рядку знаходяться три цілих числа n, t t0 (1 ≤ n ≤ 100, 1 ≤ t ≤ 10 000, 1 ≤ t0 ≤ 100) — кількість варіантів, тривалість контрольної і час, яке Коля витратить на списування завдання.

У наступних n рядках знаходиться опис варіантів. Перше число mі (1 ≤ mі ≤ 100) — кількість завдань у варіанті i. Наступні mі чисел tij (1 ≤ tij ≤ 100) — час, що Коля витратить на рішення j-го завдання i-го варіанту.

Формат вихідних даних

Для кожного варіанту виведіть на новому рядку одне ціле число — кількість завдань, які Коля встигне вирішити, якщо йому попадеться цей варіант.

Приклади

Вхідні дані
4 45 5
5 10 10 10 10 10
4 30 10 10 10
3 40 40 5
1 100

Вихідні дані
5
4
2
1

Рішення

Переберемо префікс завдань, які вирішить Коля. Знайдемо час, що він витратить, якщо буде сам вирішувати всі завдання, і максимальний час, що він витратить на одне завдання в такому випадку. Зрозуміло, що якщо він буде списувати, то треба списувати саме найдовше завдання з тих, що він робить. Тоді час, який Коля витратить, дорівнює S – max(0, M t0). Тепер знайдемо найбільший префікс, у якого цей час не перевищує t.

Завдання B. Багатоніжка
Умова

Обмеження по часу 2 секунди
Обмеження по пам'яті 256 мегабайт

В дитинстві у хлопчика Філі будинку жила багатоніжка. Всього у багатоніжки було n ніг, деякі з них праві, а деякі ліві. Кожен день багатоніжка використовувала тільки деякі з своїх ніг, але обов'язково хоча б одну ліву і хоча б одну праву.

Кожен день Філя записував собі в блокнот два числа — скільки лівих і скільки правих ніг використовувала багатоніжка в цей день.

Філя хоче за своїм записам зрозуміти, скільки лівих і скільки правих ніг було у його багатоніжки. На жаль, Філя не ідеальний і міг допустити в декількох записах помилки. Філя вважає запис lі, rі коректною, якщо у багатоніжки було хоча б lі лівих і хоча б rі правих ніг.

Допоможіть йому зрозуміти, скільки у багатоніжки могло бути лівих і правих ніг, щоб як можна більше записів були коректними.

Формат вхідних даних

Вхідні дані містять декілька тестових наборів. У першому рядку задано кількість тестів t (1 ≤ t ≤ 10 000).
Кожен з тестів описується наступним чином: у першому рядку опису тесту міститься число n (2 ≤ n ≤ 109) — сумарна кількість ніг багатоніжки, а у другому рядку число m (1 ≤ m ≤ 105) — кількість записів.

У наступних m рядках містяться по два числа lі rі (1 ≤ lі, rіn) — кількість лівих і правих ніг, використовуваних многоножкой i-й день відповідно до записів Філі, відповідно.

Сумарна кількість записів по всім тестам не перевершує 105.

Формат вихідних даних

Для кожного тесту у окремому рядку виведіть відповідь на нього — кількість лівих і правих ніг у багатоніжки, щоб коректними виявилося найбільшу можливу кількість записів.

Приклади

Вхідні дані
3
4
3
1 2
1 3
1 4
2
2
2 2
1 2
5
4
1 4
2 3
3 2
4 1

Вихідні дані
1 3
1 1
1 4

Рішення

Щоб вирішити цю задачу, можна відсортувати всі записи за кількістю лівих ніг. Далі будемо перебирати кількість лівих ніг за зростанням. Якщо лівих ніг lі, то потенційно можуть бути вірними перші i записів, а всі наступні записи точно невірні (за винятком кількості ніг, рівного lі).

Тепер потрібно дізнатися, скільки записів з перших i будуть вірні. Запис з номером j ≤ i вірна, якщо rj ≤ n – lі. Знаходження всіх таких rj є стандартною завданням і вирішується, наприклад, деревом відрізків.

Також потрібно було звернути увагу, що сума чисел у відповіді повинна бути дорівнює n, і коректно обробляти випадок, де всі записи можуть бути неправильні.

Завдання C. Бінарне дерево
Умова

Обмеження по часу 4 секунди
Обмеження по пам'яті 256 мегабайт

Студенту Васі для заліку з біоінформатики потрібно виростити повне бінарне дерево, усе листя якого мають однакову відстань до кореня.

Нагадаємо, що підвішене дерево — це зв'язний неорієнтований граф без циклів, в якому одна з вершин є коренем. Батьком вершини називається її сусід, найближчий до кореня, кореня немає батька. Інші сусіди вершини називаються її синами. Вершина, у якої немає синів, називається листом. Повне бінарне дерево — це підвішений дерево, кожна вершина якого, не є листом, має двох синів.

На жаль, під час семестру Вася занадто багато часу витрачав на олімпіади по програмуванню і не дуже стежив за зростанням свого дерева. За кілька днів до заліку Вася зрозумів, що дерево у нього зросла, але, можливо, неправильно і у нього навіть кореня немає. Вася може сам вибрати коренем дерева будь-яку його вершину і спробувати отримати з нього потрібне повне бінарне дерево, додаючи вершини. За один день Вася може додати до дерева нову вершину, зробивши її сином одного з вже існуючих.

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

При виведенні кількості днів, які йому необхідні, Вася хоче побачити лише залишок від ділення цього числа на число 109 + 7. Зверніть увагу, що Васі треба мінімізувати саме число днів, за яке він зможе завершити формування дерева, а не залишок від ділення на 109 + 7, залишок необхідно взяти безпосередньо перед виведенням.

Формат вхідних даних

Вхідні дані містять декілька тестових наборів. У першому рядку задано кількість тестів t.

Кожен з наступних t тестів описується наступним чином: у першому рядку опису тесту дано одне ціле число n (2 ≤ n ≤ 2 • 105) — кількість вершин у дереві. У наступних n – 1 рядках опису тесту подані пари чисел uі, vі (1 ≤ uі, vіn) — номери вершин, з'єднаних i-м ребром. Гарантується, що ребра утворюють дерево.

Гарантується, що сума чисел n по всім тестам не перевершує 2 • 105.

Формат вихідних даних

Виведіть відповідь для кожного тесту в окремому рядку.

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

Інакше виведіть два цілих числа — номер вершини, яку потрібно вибрати коренем, і залишок від ділення кількості днів, яке потрібно Васі, на 109 + 7. Якщо є кілька вершин, що дозволяють виконати завдання в мінімальний термін, виведіть вершину з мінімальним номером.

Приклади

Вхідні дані
3
3
1 3
3 2
4
4 2
3 2
3 1
5
1 2
1 3
1 4
1 5

Вихідні дані
3 0
2 3
-1

Рішення

Щоб мінімізувати кількість днів, які доведеться витратити Васі, потрібно мінімізувати висоту підсумкового бінарного дерева — якщо глибина листа в підсумковому дереві дорівнює h, то Вася витратить 2h – 1 – n днів на те, щоб підвісити необхідне число вершин.

Зауважимо, що якщо в дереві є вершина мірою більше 3, то завдання виконати не вийде, — у повному бінарному дереві всі вершини мають не більше трьох сусідів. Звернемо увагу, що корінь у відповіді має двох синів.

Таким чином, щоб розв'язати задачу, потрібно перебрати корінь — вершину мірою не більше 2 — й вибрати коренем таку вершину, що максимальне з відстаней від неї до всіх інших мінімально. Це і буде висота підсумкового дерева.

Завдання D. Пробірки і реактиви
Умова

Обмеження по часу 2 секунди
Обмеження по пам'яті 256 мегабайт

Сьогодні вчитель хімії дав Петі дуже відповідальне завдання — розлити реактиви по пробірках. У розпорядження йому надали n пробірок і m реактивів. Для кожної пробірки відомі minі maxі — мінімальна і максимальна сумарна кількість рідини в мілілітрах, яке може в ній перебувати, відповідно, а також номер реактиву cі і число pі. Для кожного реактиву також відомо число vі — скільки мілілітрів його є у Петі. Учитель просить Петю розлити всі реактиви так, щоб в i-й пробірці як мінімум pі відсотків від всієї рідини, в ній знаходиться, займав реактив cі, а також щоб у кожній пробірці були задоволені обмеження на minі maxі. Всі реактиви повинні бути повністю залиті. Будемо вважати, що ніяких хімічних реакцій і змін обсягу реактивів не відбувається.

Допоможіть Петрику виконати завдання вчителя або скажіть, що, як би він ні намагався зробити у нього це не вийде.

Наприклад, в першому тестовому наборі з прикладу підійде наступний відповідь:

  • У першу пробірку налити 3 мл першого реактиву і 2 мілілітра другого.
  • У другу пробірку налити 4 мл третього реактиву і 1 мілілітр другого.
  • В останню пробірку налити 3 мл четвертого реактиву і 1 мілілітр другого.
В цьому випадку всі обмеження на minі maxі виконуються, а також виконуються обмеження на відсотки реактивів у пробірках: у першій пробірці 3/5 = 60% першого реактиву, у другій пробірці 4/5 = 80% третього реактиву, а в останній пробірці 3/4 = 75% ≥ 70% четвертого реактиву. Також всі реактиви повністю залиті, тому всі вимоги, дані вчителем, виконані і відповідь вірний.

Формат вхідних даних

Вхідні дані містять декілька тестових наборів. У першому рядку задано кількість тестів t (1 ≤ t ≤ 100).

Кожен з наступних t тестів описується таким чином: у першому рядку опису тесту містить два числа n, m (1 ≤ n, m ≤ 105) — кількість пробірок і реактивів відповідно.

В i-ї з наступних n рядків міститься чотири цілих числа minі, maxі, cі, pі (1 ≤ minіmaxі ≤ 105, 1 ≤ cіm, 1 ≤ pі ≤ 100) — мінімальна і максимальна сумарна кількість мілілітрів рідини, яку можна налити в i-ю пробірку, номер реактиву та його мінімальний відсоток вмісту в пробірці відповідно.

В останньому рядку опису тесту містяться m цілих чисел vі (1 ≤ vі ≤ 105) — кількість мілілітрів i-го реактиву у Петі.

Гарантується, що сума n і сума m у всіх тестах не перевершує 105.

Формат вихідних даних

Для кожного тесту виведіть відповідь на нього.

Якщо відповідь існує, у першому рядку виведіть YES, а в i-ї з наступних n рядків виведіть спочатку число k — кількість різних реактивів i-й пробірці, а потім k пар позитивних чисел id, v — номер реактиву та його кількість у пробірці. Якщо існує кілька відповідей, дозволяється вивести будь.

Якщо відповіді на тест не існує, у єдиному рядку виведіть NO.

Відповідь буде вважатися вірним, якщо будуть виконані усі умови, зазначені в завданні, а також відносна або абсолютна похибка не буде перевищувати 10-6.

Приклади

Вхідні дані
2
3 4
5 8 1 60
4 6 3 80
3 4 4 70
3 4 4 3
3 4
6 8 1 60
4 6 3 80
3 4 4 70
3 4 4 3

Вихідні дані
YES
2 1 3.0000000000 2 2.0000000000
2 2 1.0000000000 3 4.0000000000
2 2 1.0000000000 4 3.0000000000
NO

Рішення

Наведемо конструктивний алгоритм у кілька етапів:

  • Якщо sum(mini) > sum(vi) — відповідь NO.
  • Якщо sum(maxi) < sum(vi) — відповідь NO.
  • Наллємо в кожну пробірку minipi / 100 мл реактиву ci.
  • Після цього для кожного реактиву i відсортуємо пробірки, для яких cj = i, за зростанням pj і будемо по черзі наливати в них залишився реактив номер i.
  • У кожну пробірку наллємо ще (maxj minj) pj / 100 мілілітрів i-го реактиву або менше, якщо він закінчиться.
  • Все, що залишилося від реактивів розіллємося по пробірках будь-яким способом: i-ю пробірку сумарно можна налити будь-яку кількість рідини, не перевершує summaryi • 100 / pі (summaryi — сумарна кількість рідини в ній на поточний момент).
  • Якщо розлити не вийшло і рідина залишилася — відповідь NO.
  • Єдина залишилася проблема — в якихось пробірках все ще може бути менше mini мілілітрів рідини.
  • Для виправлення цього в пробірці i спочатку перельем з усіх інших пробірок j реактиви, відмінні від cj, i-ю пробірку, так, щоб в j-й пробірці залишилося хоча б minj рідини.
  • Якщо й цього не вистачило, перельем з інших пробірок j рідина номер cj (тепер це не зіпсує умова на процентний вміст).
Після цих дій вийшло поділ реактивів на пробірки завжди буде відповідати всім умовам завдання.
Наостанок зазначимо, що в цій задачі могли бути певні проблеми з точністю. Тести журі були побудовані в цьому сенсі досить гуманно, але після туру Петро Мітрічев (якого ми вітаємо з перемогою у відбірному раунді) показав тест, в якому відбуваються суттєві втрати точності. Ми постараємося надалі уникати тонкощів з точністю в задачах з речовими числами.

Завдання E. Розмін грошей
Умова

Обмеження по часу 4 секунди
Обмеження по пам'яті 256 мегабайт

За своє довге життя Боря зібрав колекцію з n монет. Він виклав всі ці монети в ряд. При цьому i-я в ряду монета має номінал aі.

Боря збирається в чергову подорож, але у нього залишилося дуже мало часу на збори. Тому він хоче взяти деякий відрізок лежать поспіль монет і сподівається, що йому вистачить.

Боря хоче відповісти на декілька запитів. В кожному запиті Боря хоче дізнатися, яку мінімальну суму він не зможе заплатити без здачі, якщо він візьме всі монети lі-ї по rі-ю. Більш формально — він хоче знайти таке мінімальне натуральне число z, що не можна вибрати підмножину монет з номерами від lі rі, сумарний номінал яких дорівнює z.

Формат вхідних даних

У першому рядку задано два цілих числа n m (1 ≤ n, m ≤ 150 000) — кількість монет у Борі і кількість запитів. У наступному рядку задано n чисел aі (1 ≤ aі ≤ 109) — номінал i-ї монети.

У наступних m рядках задано по два числа lі rі (1 ≤ lіrіn) — опис запитів.

Формат вихідних даних

На кожен з m запитів виведіть мінімальну суму, яку можна заплатити без здачі, скориставшись монетами lі-ї по rі.

Приклади

Вхідні дані
5 5
2 1 5 3 1
1 5
1 3
1 1
2 4
2 5

Вихідні дані
13
4
1
2
11

Рішення

Розглянемо, як знайти мінімальну суму грошей, яка не може бути віддана за допомогою заданого набору монет. Будемо знаходити відповідь ітеративне. На самому початку ми можемо представити лише суму, що дорівнює нулю, і ми не використовували ніяких монет.

Нехай на черговому кроці ми розглянули всі монети, вартість яких не перевищує X, і ми можемо заплатити будь-яку суму до Y включно. Нехай сумарна вартість монет, кожна з яких коштує більше X, але не більше Y + 1, дорівнює sum. Тоді якщо sum = 0, то Y + 1 ми не зможемо представити за допомогою цього набору. Інакше перейдемо до стану, що розглянуті всі монети, вартість яких не більше Y 1, і ми можемо уявити будь-яку суму до Y + sum включно.

Зауважимо, що вартість максимальної монети, яку ми розглянули, зростає як мінімум так само швидко, як числа Фібоначчі. Значить, цей процес завершиться за O(log Answer) ітерацій.

Щоб вирішити вихідну задачу, необхідно навчитися знаходити суму чисел, менших X, на відрізку. Якщо робити це за O(log n), то можна вирішувати завдання сумарно за O(m log n log Answer).

Ця задача є стандартною. Розглянемо метод, який вимагає лінійного кількості пам'яті. Для цього відсортуємо всі числа у вихідному масиві і будемо відповідати на всі запити паралельно. На черговій ітерації для кожного запиту відомо поточне максимальну кількість грошей, яку можна отримати. Відсортуємо всі запити по ньому. Далі будемо додавати в дерево Фенвіка числа вихідного масиву в порядку зростання і в потрібний момент оновлювати кордон для чергового запиту.

Завдання F
Умова

Обмеження по часу 5 секунд
Обмеження по пам'яті 256 мегабайт

Гном Паша пише відбірний раунд Gnome Math Cup. В якості завдання F запропонована наступна.

Дано n натуральних чисел a1, a2, ..., an і натуральне число d, потрібно знайти будь-який набір ненульових цілих чисел x1, x2, ..., xn, такий, що a1x1 + a2x2 +… + anxn = d. Так як у гномів погано з множенням і складанням, всі числа d, aі не перевищують 106, а числа xі повинні бути від -106 106, але не рівні 0.

Допоможіть Паші знайти хоча б один набір xі, який задовольняє умові задачі, або повідомте йому, що організатори зробили погані тести і відповіді не існує.

Формат вхідних даних

Перший рядок вхідних даних містить t — кількість тестів. Кожен тест задається двома рядками. Перший рядок містить два числа n d (1 ≤ n ≤ 105, 1 ≤ d ≤ 106). Другий рядок містить n чисел aі (1 ≤ aі ≤ 106). Сума n по всім тестам не перевершує 105.

Формат вихідних даних

Виведіть відповідь на кожен тест. Якщо потрібний набір xі існує, то у першому рядку виведіть YES і в другій виведіть будь-який відповідний набір. Інакше у єдиному рядку відповіді на тест виведіть NO.

Приклади

Вхідні дані
2
2 1
2 3
3 3
2 3 1000

Вихідні дані
YES
2 -1
YES
503 -1 -1

Рішення

Відповідь NO буває тільки в одному випадку, коли d не ділиться на найбільший дільник чисел aі. В будь-якому іншому випадку відповідь завжди існує. Для початку ми навчимося отримувати хоч якусь відповідь без обмеження на значення, попередньо поділивши всі aі d на gcd(a1, ..., an). Якщо n = 1, то x1 = d/a1. В інших випадках ми будемо підбирати для кожного префікса [1, p] такі xi, p, a1x1, p +… + apxp, p = gcd(a1, ..., ap). Робиться це індуктивним методом. x1, 1 = 1. Нехай ми вже знайшли xi, p і хочемо знайти xi, p + 1. За допомогою розширеного алгоритму Евкліда ми знаходимо s t: s • gcd(a1, ..., ap) + tap + 1 = gcd(gcd(a1, ..., ap), ap + 1) = gcd(a1, ..., ap + 1). Тоді для i ≤ p xi, p + 1 = s xi, p xp + 1, p + 1 = t. Отримавши xi, n, обчислюємо xі = d/gcd(a1, ..., an)xi, n = dxi, n. Таке рішення працює за O(n2), що не підходить під обмеження. Щоб скоротити час роботи, ми оберемо серед aі підмножина, у якого найбільший загальний дільник такий же, як у всього безлічі, і таке, що не можна зменшити. Для цього ми будемо перебирати від a1 an і брати число домен, якщо воно зменшує кількість різних простих дільників. Таким чином, вибране підмножина містить не більше 7 елементів, так як максимальна кількість простих дільників у кількості, меншої або рівної 106, дорівнює 7. Для чисел з підмножини ми запускаємо описаний алгоритм, а для чисел, що не увійшли до безліч, просто виставляємо xі = 0.

Тепер алгоритм працює за O(n), але не виконуються умови, що xі по модулю не перевищують 106 і серед них не повинно бути нулів. Для цього опишемо процедуру нормалізації. Спочатку виконаємо для xі перша умова. В першу чергу зробимо все xі i > 1 неотрицательными і меншими a1. Це робиться простою операцією еквівалентного зміни: ми віднімаємо з x1 kaі і додаємо до xі ka1, де k = (xі mod a1 xі)/a1. Відзначимо, що результати виконання операції влазять у 64-бітний тип даних, так як x1 по модулю не може перевершити |d – a2 x2 –… an xn| < 106 • 106 • 105. Тепер пройдемося по всіх xі, починаючи з другого, до останнього і з кожним будемо послідовно робити операцію: відняти a1 xі додати aі x1. Зауважимо, що існує i таке, що після застосування операції до x1, ..., xі вийшло 0 ≥ x1 ≥ -106. Нехай не існує такого i, тоді xі стали негативними, чого статися не могло, так як a1 x1 +… an xn дає d, тобто додатне число. Після того як ми навчилися одержувати |xі| ≤ 106, залишилося зробити їх ненульовими. Розіб'ємо всі нулі на пари, можливо крім одного. У кожній парі i j присвоїмо xі = aj xj = –aі. У нас, можливо, залишився єдиний індекс p, для якого xp = 0. Ми розглянемо кілька випадків:

  • Якщо існує xj, яка за модулем дорівнює ap, тоді ми застосовуємо операцію: віднімаємо sign(xj)ap xj і додаємо sign(xj)aj xp.
  • Якщо ж такого xj не існує, але ap ≤ 5 • 105, тоді до будь-якого xj можна застосувати операцію: додати sign(xj)ap xj і відняти sign(xj)ap xp.
  • В іншому випадку повинно знайтися aq, таке, що aq ≠ ap. Якщо такого не існує, то все aі = a1, а значить, через нормування на найбільший загальний дільник aі = a1 = 1 і повинен був здійснитися другий випадок. Ми проводимо операцію: віднімемо sign(xj)ap xq і додамо sign(xj)aq xp. Після цього xq дорівнює нулю. Але тепер, якщо n > 2, для q виконається перший випадок, а якщо n = 2, то для q виконається другий випадок, так як d = aq ap ≤ 106.
Слід зазначити, що операцію нормування потрібно проводити для кожного префікса в алгоритмі, описаному в першому абзаці числа поміщалися в 64-бітний тип даних. За дальшими подробицями можна звернутися до коду рішення журі, викладеному разом з тестами.

***
Чемпіонат Russian Code Cup входить в число ініціатив Mail.Ru Group, спрямованих на розвиток російської IT-галузі і об'єднаних ресурсом IT.Mail.Ru. Платформа IT.Mail.Ru створена для тих, хто захоплюється IT і прагне професійно розвиватися в цій сфері. Проект об'єднує чемпіонати AI Cup Russian, Russian Code Cup Russian Developers Cup, освітні проекти Технопарк в МДТУ їм. Баумана, Техносфера в МДУ їм. М. в. Ломоносова і Технотрек в МФТІ. Крім того, на IT.Mail.Ru можна з допомогою тестів перевірити свої знання з популярних мов програмування, дізнатися важливі новини зі світу IT, відвідати або подивитися трансляції з профільних заходів та лекції на IT-тематику.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.