OCPC2021 K: Нобелевская премия

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 500 мс
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Нобелевская премия

Дед Архип и дед Игнат, постояльцы палаты номер 17 заведения «Покосившийся Скворечник», убеждены, что они – великие математики – Блез Паскаль и Пьер Ферма соответственно. А как ещё должны проводить время математики, если не играя друг с другом в азартные игры? Вот и дед Архип с дедом Игнатом придумали себе развлечение – они раздобыли три баночки с таблетками умиротворения: по одной им вручили санитары, а третью прикарманил дед Архип («Во имя науки!» – воскликнул он, унося таблетки), воспользовавшись тем, что их соседа, деда Панаса, сморило прослушивание доказательства Великой теоремы Игната.

Правила игры следующие: игроки ходят по очереди в порядке старшинства. За один ход великий математик выбирает целое положительное число x и съедает x таблеток из какой-то одной баночки, либо съедает по x таблеток из всех трёх баночек сразу. Проигрывает тот, кто не может сделать ход, а его противник награждается магарычем от деда Пахома, убеждённого, что он – Альфред Нобель. Магарычем в области экономики, разумеется, ведь именно так награждают лучших математиков.

Дед Архип и дед Игнат с удовольствием бы сыграли, чтобы установить победителя, но предыдущий опыт подобных развлечений убедил их, что они необъяснимым образом теряют интерес к игре уже после первого хода. Поэтому они просят Вас назвать победителя по исходным данным, а таблетки они оставят для завтрашней игры. Не сомневайтесь, что великие математики всегда ходят оптимальным образом.

Единственная строка ввода содержит три целых числа abc (0 ≤ abc ≤ 1000) – количество таблеток в каждой из трёх баночек.

Выведите единственную строку «Ignat», если Нобелевскую премию получит дед Игнат, и «Arkhip», если удача на стороне деда Архипа.

Примеры

Входные данные Результат работы
2 0 2 Arkhip
1 2 4 Ignat

Видеоразбор решения задач здесь.

Related Images:

OCPC2021 J: Театр теней

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 3 с
Ограничение реального времени: 6 с
Ограничение памяти: 256M

Театр теней

Тиктокеры Стас и Ян, постояльцы палаты номер 66 заведения «Покосившийся Скворечник», решили устроить перфоманс в прямом эфире. Они разместили на прямоугольном полу своей палаты n свечей в разных точках и готовятся провести представление, состоящее из m актов. В каждом акте должен гореть только определённый набор свечей, который будет таким образом создавать новую картину из теней на стене палаты, остальные свечи должны быть потушены. Область, попадающая в кадр, имеет ширину w, длину l, по ширине перекрывает палату целиком, а по длине оставляет небольшое пространство слева и справа, как показано на рисунке.

Сами тиктокеры в кадре появляться не должны, с этой целью они могут находиться либо у левой, либо у правой стенки палаты за кадром. Чтобы тушить и зажигать свечи, Стас и Ян могут делать перерывы между актами перфоманса, во время которых стрим отключается, и они будут выбегать в кадр: Стас будет только зажигать свечи, а Ян – только гасить, после чего они должны успеть скрыться из кадра до начала нового акта. Перед перфомансом Стас находится за кадром слева, а Ян – за кадром справа. Также изначально зажжены свечи, необходимые для первого акта.

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

Первая строка ввода содержит пять чисел – wlv1v2 и n (1 ≤ wl ≤ 50, 1 ≤ v1v2 ≤ 20, 1 ≤ n ≤ 15) – размеры кадра, скорости Стаса и Яна и количество свечей на полу. Далее идут n строк с координатами свечей xiyi (0 < xi < l, 0 < yi < w). Следующая строка содержит число m (1 ≤ m ≤ 104) – количество актов перфоманса. Далее идут m строк, каждая из которых начинается с количества свечей, которые должны гореть в очередном акте и продолжается номерами этих свечей.

Единственная строка вывода должна содержать число – минимально возможное суммарное время перерывов между актами перфоманса с точностью до 10-5.

Примеры

Входные данные Результат работы
5 6 1 1 3
1 2
3 4
5 3
1
1 3
0.000000
5 6 1 1 3
1 2
3 4
5 3
3
1 3
2 1 2
3 1 2 3
8.828427

Видеоразбор решения задачи здесь.

Related Images:

OCPC2021: I Белка в колесе

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 5 с
Ограничение реального времени: 10 с
Ограничение памяти: 256M

Белка в колесе

Журналистка Ксюша, постоялица палаты номер 13 заведения «Покосившийся Скворечник», убеждена, что она – белка. Сейчас, стоя у окна своей палаты, она смотрит на растущее за окном дерево (как известно любой белке, это связный граф без циклов) и воображает, как резвится, перебегая по нему с ветки на ветку и обратно. Главред Аркаша, сосед Ксюши, возмущён таким бесцельным и беспорядочным расходованием энергии, поэтому он хочет соорудить из какой-то части (возможно, всего) дерева колесо, то есть, добавить в граф несколько рёбер, чтобы создать цикл, по которому и будет бегать Ксюша, вырабатывая сверхценные идеи для издания. Но, к сожалению, у Аркаши есть всего две подтяжки, которые он готов пожертвовать на это благое дело, а значит, он может добавить не более, чем два ребра в дерево, при этом, он хочет получить цикл максимальной длины, и каждая вершина должна входить в него не более одного раза, не то Ксюша запутается и выдаст что-то не передовое или социально неодобряемое. Длина цикла, как знает любой главред, считается по количеству рёбер в нём. Поскольку Аркаша не привык работать сам, он ждёт, что Вы подскажете ему максимальную длину колеса для белки и между какими вершинами вешать подтяжки, а не то он Вас закенселит.

Первая строка ввода содержит единственное целое число n (3 ≤ n ≤ 105) – количество вершин дерева, растущего за окном. Следующие n-1 строк содержат пары целых чисел – номера вершин дерева, соединённых ребрами.

Первая строка вывода должна содержать одно число – максимальную достижимую длину колеса. Следующие 1 или 2 строки должны содержать пары целых чисел – какие пары вершин нужно соединить подтяжками, чтобы получить колесо нужной длины.

Примеры

Входные данные Результат работы
4
1 2
2 3
3 4
4
1 4
4
1 2
1 3
1 4
4
2 3
2 4

Видеоразбор решения задачи здесь.

Related Images:

OCPC2021 H: Счастья всем даром!

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 1 с
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Счастья всем даром!

В заведении «Покосившийся Скворечник» проходит традиционная воскресная перекличка. Во время этого мероприятия все постояльцы выстраиваются в ряд и по очереди, начиная с самого правого, выкрикивают свой порядковый номер в ряду. Кондуктор Кондрат, постоялец палаты номер 11, убежден, что если сегодня он выкрикнет счастливый номер, то удача наконец-то повернётся к нему лицом, и ему наконец-то выплатят зарплату за все те годы, что он обилечивал каждого встречного в «Покосившемся Скворечнике». Любому кондуктору известно, что счастливое число – это такое число, сумма цифр на чётных позициях которого совпадает с суммой на нечётных. Только что Кондрат услышал номер, который выкрикнул его сосед справа и теперь у кондуктора есть всего две секунды, чтобы понять, какой следующий номер – счастливый и, сломя голову, побежать занимать соответствующее место в ряду. Вы – его сосед слева, шепните правильный ответ Кондрату и на радостях он подарит Вам проездной!

Единственная строка ввода содержит натуральное число – номер, который выкрикнул сосед Кондрата. Этот номер содержит не более 100 цифр.

Выведите одно число – следующий по порядку счастливый номер.

Примеры

Входные данные Результат работы
123123 123134
99 110

Видеоразбор решения задачи здесь.

Related Images:

OCPC021 G: Электрик возвращается

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 1 с
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Электрик возвращается

Электрик Геннадий, постоялец палаты номер 404 заведения «Покосившийся Скворечник», прокрался ночью к ближайшей ЛЭП, чтобы наконец воплотить в жизнь свой план – отрезать кусок провода, находящийся между двумя соседними опорами, и отомстить лживой розетке из предыдущей задачи.

Он планирует реализовать это следующим образом: сначала просто забраться на вершину одной из опор, отрезать провод, закреплённый там, после чего спуститься на некоторую высоту вниз, возможно до земли. Далее Геннадий рассчитывает воспользоваться способностями человека-паука, которые, по его убеждению, открылись в нём после недавнего удара током: он выстрелит паутиной в некоторую произвольную точку соседнего столба, оттолкнется от первого столба и спустится по дуге окружности либо до второго столба, либо до земли. Разница высот в начале и конце такого спуска не должна превышать некоторую величину l, иначе наш новоявленный человек-паук рискует слишком сильно разогнаться и превратиться в человека-лепёшку. Затем электрик поднимется на вершину второго столба, чтобы отрезать закреплённый там провод, и спустится на землю.


Высоты столбов – h1 и h2, расстояние между ними – d. Геннадий не очень любит лазать вверх, поэтому он хочет разработать план таким образом, чтобы суммарная дистанция подъёмов была минимально возможной. Раз уж Вы взялись помогать ему, то доведите начатое до конца!

Единственная строка ввода содержит четыре целых числа dh1h2l (1 ≤ dh1h2l ≤ 106).

Выведите одно число – минимальную суммарную дистанцию подъёма Геннадия с точностью не хуже 10-5.

Примеры

Входные данные Результат работы
5 5 5 5 10.00000
4 5 8 5 10.00000
4 8 5 1 13.00000
3 4 6 1 9.00000

Видеоразбор решения задачи здесь.

Related Images:

OCPC2021 F: Электрик наносит ответный удар

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 1 с
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Электрик наносит ответный удар

В заведении «Покосившийся Скворечник» главврач экономит на зарплате системного администратора, поэтому эту должность в свободное от уколов время занимает электрик Геннадий из палаты номер 404. На сегодняшнем дежурстве одна из розеток внезапно заговорила с Геннадием и посулила тому суперспособности, если он её раскрутит. Результатом их общения, однако, стал лишь удар тока по нерадивому электрику, и теперь Геннадий задумал месть: он устроит лживой розетке Очень Длинное Замыкание!

Дата-центр «Покосившегося Скворечника» устроен следующим образом: помимо разной аппаратуры, из стены в ряд торчат 2∙n коннекторов: это n штепселей и n розеток. Геннадий планирует разбить их на пары розетка-штепсель и соединить каждую пару одним проводом таким образом, что штепсель всегда находится левее соответствующей розетки – эту идею ему навеяли правила средневекового этикета. Чтобы замыкание было Очень Длинным, Геннадий хочет, чтобы суммарная длина проводов, использованных для его коварного замысла, была максимально возможной. Помогите ему! Ну, или не мешайте хотя бы, и просто подскажите, провод какой длины он должен отрезать от соседней линии электропередач, чтобы распилить его на столь нужные ему провода.

Первая строка ввода содержит целое число n (2 ≤ n ≤ 1000). Вторая строка содержит n целых чисел – координаты штепселей слева направо. Третья строка содержит n чисел – координаты розеток слева направо. Все числа во второй и третьей строках различны и находятся в диапазоне от 0 до 105.

Выведите одно число – суммарную длину проводов, необходимых, чтобы устроить Очень Длинное Замыкание. Гарантируется, что существует хотя бы один способ соединения штепселей с розетками без нарушения правил средневекового этикета.

Примеры

Входные данные Результат работы
2
1 4
6 8
9
2
1 4
2 5
2

Видеоразбор решения задачи здесь.

Related Images:

OCPC2021 E: Объясните теперь нам, вахтёры…

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 500 мс
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Объясните теперь нам, вахтёры…

В заведении «Покосившийся Скворечник» ЧП: на фоне ежеквартального обострения синдрома вахтёра из палаты номер 99 вырвался ночной сторож Михалыч и перегородил вход в уборную. Для пропуска внутрь он требует пароль, который он тут же записал на стене в виде строки из m строчных латинских символов. Но не всё так просто: недостаточно назвать пароль тщеславному Михалычу – нужно составить его из букв стихотворения, сочиненного ночным сторожем. И действительно, над паролем Михалыч записал стихи: n строк по m строчных латинских символов каждая. Чтобы получить искомый пароль, над ними разрешено проделывать следующую операцию: выбрать две различные строки с номерами i и j, выбрать номер символа k, а затем поменять местами k-й символ в строках номер i и j. Например, если мы меняем 3-й символ в паре строк «abcde» и «fghij», то получим «abhde» и «fgcij». Так нужно делать до тех пор, пока одна из строк не совпадёт с паролем.

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

Первая строка ввода содержит целое число n (2 ≤ n ≤ 100) – количество строк в стихотворении Михалыча. Каждая из последующих n строк состоит из строчных латинских символов и имеет одинаковую длину m (2 ≤ m ≤ 100). Последняя строка содержит пароль Михалыча длины m.

Первая строка вывода должна содержать минимальное число x операций над строками. Если получить пароль никак невозможно, выведите -1. В следующих x строках, если возможно получить пароль, выведите последовательность операций в формате i j k – номера первой и второй строк стихотворения Михалыча, над которыми производится операция обмена и номер символа в этих строках.

Примеры

Входные данные Результат работы
3
cab
abc
bca
cba
2
1 3 3
1 2 2
3
dbc
aeb
cca
acd
-1

Видео разбор решения задачи здесь.

Related Images:

OCPC2021 D: Столовая

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 2 с
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Столовая

В столовой заведения «Покосившийся Скворечник» имеется ровно k тарелок, а в самом заведении – n палат. По старой традиции, чтобы постояльцы не пугались новых знакомых и не обменивались симптомами, их приводят в столовую так, чтобы одновременно там находились только обитатели одной палаты. При этом, порядок посещения столовой палатами строго зафиксирован – от меньшего номера к большему.

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

Первая строка ввода содержит два целых числа n и k (1 ≤ n ≤ 105, 1 ≤ k ≤ 105) – количество палат и тарелок, соответственно. Следующие n строк содержат по 2 целых числа ai и bi (0 ≤ ai + bi ≤ k) – количество постояльцев в очередной палате, моющих и не моющих за собой посуду, соответственно.

Выведите одно число – количество тарелок, оставшихся чистыми к концу смены, при оптимальной раздаче посуды.

Примеры

Входные данные Результат работы
2 4
1 2
1 1

3

Видеоразбор решения здесь.

Related Images:

OCPC2021 C: Перепись чисел

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 1 с
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Перепись чисел

Учительница младших классов Марь Ивановна, постоялица палаты номер 9 3/4 заведения «Покосившийся Скворечник», насмотрелась «Гарри Поттера» и теперь боится, что Волдеморт сотрёт у неё из памяти какое-нибудь число. Чтобы не допустить этого преступления, Марь Ивановна решила выписать все числа от 1 до n (числа, большие, чем n, ей для работы всё равно не пригодятся) подряд в одну строку на стене палаты. При этом, для экономии времени (Волдеморт уже рядом!), она решила приписывать очередное число к своей строке только в том случае, если его десятичная запись еще не содержится в уже записанной строке. Например, в строке «1234567891011» уже содержится запись числа 12, а значит, приписывать это число не нужно.

Сосед Марь Ивановны, трудовик Василий Семёныч, убеждён, что Волдеморт уже стёр какое-то число из памяти учительницы младших классов. Чтобы удостовериться в своей правоте, он требует, чтобы Вы показали ему, как должна выглядеть верная строка, составленная по правилам Марь Ивановны, для сравнения с тем, что в итоге появится на стене палаты. В награду за помощь он обещает выстрогать бузинную палочку для вас. Поскольку в руках у Василия Семёныча лобзик, лучше с ним не спорить!

На ввод поступает единственное целое число n (1 ≤ n ≤ 105) – максимальное число, важное для работы учительницы младших классов.

Выведите одну строку, содержащую запись всех чисел от 1 до n по правилам Марь Ивановны.

Примеры

Входные данные Результат работы
1 1
4 1234
15

Видеоразбор решения здесь.

Related Images:

OCPC2021 B: Палиндромонойя

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 500 мс
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Палиндромонойя

Студент Илья, постоялец палаты номер 101 заведения «Покосившийся Скворечник», попавший сюда во время сессии на почве экзамена по программированию, убеждён, что его повсюду преследуют затаившиеся палиндромы. «Они среди нас! Как же вы этого не замечаете?!» – то и дело слышат от него нянечки Алла и Анна. По убеждению Ильи, палиндром – это слово, читающееся одинаково, как слева направо, так и справа налево. Если же на первый взгляд слово таковым не является, то студент не опускает рук и переносит буквы по одной из начала слова в конец, пока оно не станет палиндромом. Если из слова таким образом удалось получить палиндром за 0 или более операций, Илья называет его затаившимся палиндромом, после чего студент начинает бегать по потолку с воплями отчаяния, чем доставляет неудобства окружающим. Например, Илью может довести до исступления слово «масса», ведь из него можно получить «самас», перенеся 3 буквы из начала в конец. Главврач хочет выкинуть из палаты номер 101 Илью, но вместо этого выкинет все предметы, названия которых являются затаившимися палиндромами. Осталось только проверить их все, а здесь без программы не обойтись!

На ввод поступает строка, содержащая одно слово, длиной от 1 до 100 латинских строчных букв.

Выведите одну строку: «yes» без кавычек, если предмет с этим названием стоит выбросить и «no» без кавычек, если его стоит оставить в палате номер 101.

Примеры

Входные данные Результат работы
array yes
iliya no
anna< yes<

Ссылки

Related Images:

OCPC2021 A: Колёса деда Панаса

Вы можете зарегистрироваться и решать эту задачу здесь.

Ограничение времени: 500 мс
Ограничение реального времени: 5 с
Ограничение памяти: 256M

Колёса деда Панаса

Дед Панас, постоялец палаты номер 17 заведения «Покосившийся Скворечник», срочно должен был принять свои таблетки умиротворения. К сожалению, нянечка рассыпала их по столу и теперь дед Панас твёрдо уверен, что он – Генри Форд, а на столе лежат колёса, из которых нужно собирать автомобили и мотоциклы. Сосед деда Панаса, дед Архип, также не дождавшийся своих таблеток, убеждён, что он – Блез Паскаль, и, заметив, что колёс на столе четное количество, донимает нянечку вопросом: «Сколькими способами можно распределить эти колёса между автомобилями и мотоциклами так, чтобы не оставалось лишних?» Поскольку дед Архип не уймётся, пока не получит ответа, и будет мешать нянечке собирать таблетки со стола, на помощь позвали вас и просят подсказать ей правильный ответ.

На ввод поступает единственное целое четное число n (2 ≤ n ≤ 109) – количество таблеток на столе.

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

Примеры

Входные данные Результат работы
6 2

Видеоразбор решения здесь.

Related Images:

e-olymp 1821. Comparing Answers

Problem

In a place in Southwestern Europe, the name of which I do not wish to recall, not long ago there were $n$ cities connected by unidirectional roads, with possibly more than one road connecting a city to another one, or even to itself. As a homework assignment for your geography class, you need to calculate the number of paths of length exactly two that were between each pair of cities. However, you’ve been too busy celebrating the Spanish victory in the World Cup, so now you are copying the answers from your friend. You would like to make sure his answers are correct before handing in your homework.

Input

The input consists of several test cases, separated by single blank lines. Each test case begins with a line containing the integer $n$ $(1 \leqslant n \leqslant 1000)$. The following $n$ lines contain $n$ elements each, with element $j$ of line $i$ being the number of roads from city $i$ to city $j$ (a number between $0$ and $10$, inclusive). After that, there will be $n$ lines. Each will contain $n$ elements, with element $j$ of line $i$ being the answer from your friend for the number of length-$2$ paths from city $i$ to city $j$; it will be an integer between $0$ and $100000$ inclusive.

The test cases will finish with a line containing only the number zero (also preceded by a blank line).

Note: Large input file; use fast I/O routines.

Output

For each case, your program should output a line. The content of this line should be «YES» if your classmate’s solution to the assignment is right, and «NO» otherwise.

Tests

Input Output
1 3
2 0 1
1 0 3
1 1 0
5 1 2
5 3 1
3 0 43
2 0 1
1 0 3
1 1 0
5 1 2
5 3 2
3 0 40
YES
NO
2 5
1 2 7 8 9
4 5 8 7 3
1 0 2 5 6
1 0 0 5 4
1 7 2 5 9
33 75 55 142 170
42 54 90 157 154
14 44 23 73 95
10 30 15 53 65
45 100 85 137 1435
1 2 7 8 9
4 5 8 7 3
1 0 2 5 6
1 0 0 5 4
1 7 2 5 9
33 75 55 142 170
42 4 90 157 154
14 44 23 73 95
10 30 15 53 65
45 100 85 137 1430
YES
NO
3 1
2
21
2
40
NO
YES
4 9
1 5 7 9 10 6 3 3 6
10 2 0 5 10 4 3 3 5
7 10 4 1 4 0 4 4 2
5 4 0 1 7 0 5 3 2
7 0 6 1 7 5 2 2 2
7 4 0 1 1 8 6 6 3
0 4 9 2 1 8 0 3 7
8 7 7 3 5 0 10 8 2
1 0 5 8 8 8 3 3 1
287 178 173 129 293 196 195 180 134
182 123 203 174 287 214 150 143 144
202 143 163 158 261 150 126 128 148
125 78 153 108 182 137 82 89 109
156 141 157 108 183 149 120 120 105
166 145 166 147 192 199 157 161 147
207 159 98 105 176 141 159 149 81
243 232 270 182 300 197 184 192 201
213 152 128 61 176 142 160 147 1000
YES

Code

Solution

The problem statement says that element $j$ of line $i$ of the matrix corresponds to the number of unidirectional roads from city $i$ to city $j$. Thus, we have an adjacency matrix of a directed unweighted graph. We need to find the number of paths of fixed length $k = 2$ for each pair of cities and compare them to our friend’s answer from the output. Adjacency matrix $g_{n \times n}$ of a directed unweighted graph contains the number of routes of length $k = 1$  between each pair of vertices. The solution is iterative: adjacency matrix $g$ corresponds to paths of length $k = 1$. Let $g = d_k$. For $k + 1$ we have: $d_{k+1}[i][j] = \sum\limits_{p=1}^n d_k[i][p] \cdot g[p][j]$, i.e. the product of matrices $d_k$ and $g$. Conclusion: to count the routes of fixed length we have to raise the adjacence matrix to the correspondent power.

Testcases are processed one at a time and after each the answer is given. Firstly, two 2D arrays of size $n \times n$ are initialized and entered: one for storing the matrix with the amounts of paths and the other with our friend’s answers. There is a warning about a big input file in the problem statement. Thus we use C style for I/O operations. Secondly, the first matrix is squared and the results are compared to the friend’s answers one by one. Once an error is detected the loop ends and the answer «NO» is displayed. Otherwise the loop reaches its end and «YES» is displayed. It is necessary that both arrays are deleted before processing the next testcase to prevent memory leaks.

Links&References

Related Images:

e-olymp 7213. Шашка на кубе

Условие

Поверхность куба отрезками, параллельными рёбрам куба, разделена на квадратные клетки, длина сторон которых в $l$ (нечетное натуральное число) раз меньше длины ребра куба. Шашку передвигают за один ход из клетки на произвольную смежную с ней клетку (что имеет с данной общую сторону).

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

Входные данные

Содержит натуральные числа $l$ и $m$ ($l < 52$, $m < 200$).

Выходные данные

Вывести искомое количество способов.

Тесты

l m вывод
3 3 1
3 4 0
3 5 25
51 199 4009263689513240276071196173369495212494629453793821392879244551766927964742684514532573281589075237363501397360
3 199 11954860546705755218324706261555627152268568460810054501274297031890136116190373877274924800908756150285132065690107399

Код

Решение

Из условия можно понять, что задача про специфического вида граф, по которому движется шашка. Его вершинами являются клетки на гранях куба, а дуги лежат между клетками с общими границами. Очевидно количество путей за $m$ шагов до любой точки в графе будет равняться сумме количества путей за $m-1$ шагов ко всем соседним вершинам, то есть мы можем получать решение задачи для $m$ шагов из решения меньшей задачи для $m-1$ шагов, из чего можно понять что это задача на динамическое программирование.
Для решения создадим массив со всеми вершинами и будем хранить в нём количество путей к каждой из них на i-ом шаге. Удобнее всего задать такой массив как 6 числовых матриц размером $ l \times l$, по одной на каждую грань куба.

Раскладка шести граней куба с переходами между границами

Соседство будем определять, прибавляя или отнимая единицу от одной из координат клетки в матрице, например $(x-1, y)$ всегда будет соседом $(x, y)$, не считая крайних случаев, когда $x-1$ будет меньше нуля. Такие ситуации в коде обрабатывает функция FixNeighbor(...), в которой прописаны все подобные крайние случаи.

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

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

Оптимизированный вариант хранения куба

Так как для получения значения клетки через $i$ шагов нужны значения всех её соседей через $i-1$ шагов, а для получения значения соседей через $i$ шагов нужно значение клетки через $i-1$ шагов, нам не хватит только одного массива для перезаписи, надо использовать минимум два для хранения предыдущего и нынешнего состояния. В программе это реализовано с помощью булевой переменной flag — сначала мы вычисляем следующее состояние на основании 0-ого массива ( flag), записывая результат 1-ый ( !flag), а потом инвертируем значение переменной на противоположное и массивы в алгоритме меняются местами.

Ссылки

Related Images:

OCPC-2019. Разбор задач

Прочитать условия задач OCPC-2019 и отправить на проверку свое решение можно на acm.pp.ua. Регистрация свободная.

A. Ахиллес и черепаха

Поскольку Ахиллес бежит быстрее черепахи, но не должен ее обогнать, нас интересует точка, в которой он ее догонит. Для этого вначале найдем время, за которое Ахиллес догонит черепаху: $t =\frac{ x_t — x_a}{v_a — v_t}$. Теперь найдем координату, в которую в этот момент прибежит Ахиллес (и черепаха тоже): $x = x_a + v_a \cdot t$. Это число и будет ответом.

B. Буковель

Заметим, что расстоянием между двумя вершинами в нашей задаче является упорядоченная пара {количество подъемов, количество спусков}. Значит, сравнивая 2 пути, нужно сравнивать их сначала по первому параметру, затем по второму. Это сравнение уже реализовано в C++ в структуре std::pair<int, int>. Теперь просто построим наш граф, где весом каждого ребра будет пара {1, 0}, если это подъем, и {0, 1}, если это спуск.  Запустим на нем алгоритм Дейкстры — он найдет кратчайшее расстояние. Сложность алгоритма $O(n \cdot \log m)$

C. Свидание

Заметим, что период от одного «любит» до следующего занимает ровно $k+1$ лепесток. При этом номера «счастливых» лепестков такие: $1$, $k+2$, $2 \cdot k + 3$… То есть, эти числа дают остаток $1$ по модулю $k+1$. Все, что нужно, проверить, дает ли такой же остаток число $n$.

D. Дивный новый мир

Отсортируем всех студентов по возрастанию оценок. Понятно, что в оптимальном решении, если остались не отчисленными какие-то студенты, то они в этом массиве будут идти подряд. Теперь переберем все возможные диапазоны из ровно $n-k$ студентов — это минимальное количество, которое можно оставить. Пройдемся по нашему массиву «окном» {i, i + n - k - 1}, где $i$ — текущий кандидат на минимальную границу диапазона оценок, а $i + n — k — 1$ — на максимальную. Будем заменять ответ текущим кандидатом, в случае, если новый диапазон не шире имеющегося. Сложность алгоритма $O(n \cdot \log n)$.

E. Энигма

Название задачи намекает, что надо расшифровать текст. И действительно — условие зашифровано. Поскольку все задачи данного контеста начинаются с «Ни для кого не секрет, что студенты ОНУ…», то у вас уже есть ключ. По нему можно понять, что к первому символу слова всегда прибавляется $1$, ко второму — $2$ и т.д. Это дает возможность написать программу и расшифровать условие, в котором сказано, что шифруются только латинские буквы и цифры, причем большие буквы заменяются большими, строчные — строчными, цифры — цифрами, а слова разделяются пробелами, т.е. пока не встретим пробел или конец строки, слово продолжается. Далее пишем простой конечный автомат и обрабатываем ввод посимвольно. Важно не читать ввод по словам, поскольку между двумя соседними словами может быть несколько пробелов и нужно сохранить их все. Сложность алгоритма $O(n)$

F. Fiasco del ACM

Будем обрабатывать отдельно «победные» контракты, отдельно — «ничейно-победные». Для простоты рассмотрим решение только для контрактов первого типа. Пусть у нас есть отрезок из $k$ побед подряд и мы добавляем еще одну победу. Тогда призовые команды увеличатся на $\sum_{i=1}^{k+1}w_i$, где $w_i$ — сумма денег за контракты длины ровно $i$. Действительно, в $k+1$-й ячейке закончатся победные серии длины $1$, $2$,… $k+1$. Таким образом мы можем посчитать для строк всех длин призовые за них. Обозначим такой массив $s$. Если накапливать сумму $\sum_{i=1}^{k}w_i$, а не считать ее каждый раз заново, то все эти вычисления займут $O(g)$ операций.

Теперь пусть у нас есть ячейка, где мы не выиграли. Например, «WWWDWWWWW». Чтобы посчитать сколько денег мы потеряли в этом матче, найдем максимальную длину побед слева и максимальную длину побед справа. Пусть это числа $w_l$ и $w_r$. В нашем примере $w_l=3$, $w_r=5$. Если заменить теперь ничью на победу, то у нас пропадут 2 выигрышных участка длины $w_l$ и $w_r$, зато появится один большой длины $w_l+w_r+1$. Значит, недополученная в матче сумма равна $s[w_l+w_r+1]-s[w_l]-s[w_r]$. Для получения ответа нужно сложить все такие числа для матчей, где мы не победили.

Теперь осталось научиться быстро считать $w_l$ и $w_r$. Научимся для $w_l$, для $w_r$ это делается абсолютно аналогично. Будем накапливать «хвост» слева в переменной $l$. Если текущий символ ‘W’, увеличим переменную на $1$. Иначе — обнулим. Будем заносить результаты в массив. Сложность всего решения $O(g)$.

G. Героиня оптимизации

Заметим, что для $k$ человек будет совершено $k \cdot (k-1)$ нажатий. Чтобы в памяти осталось ровно 0 нажатий, необходимо и достаточно, чтобы $k \cdot (k-1) \equiv 0 \mod n$. Поскольку $gcd(k, k-1) = 1$, из предыдущего тождества можно вывести систему новых:

$k \equiv 0 \mod a$
$k \equiv 1 \mod b$
$a \cdot b = n$
$gcd(a, b) = 1$

Из китайской теоремы об остатках следует, что для каждой такой системы будет существовать ровно одно решение на диапазоне $[0, n-1]$. Осталось посчитать сколько таких систем существует. А их ровно столько, сколько существует пар делителей $a, b: a \cdot b = n, gcd(a, b) = 1$. Поскольку у $a$ и $b$ нет общих простых делителей, это означает, что если какой-то простой делитель $n$ попал в $a$, то и все остальные такие же делители попадут в $a$. Поэтому количество различных значений $a$ равно количеству способов выбрать набор различных простых делителей числа $n$. Это $2^{cnt}$, где $cnt$ — количество различных простых делителей $n$.

Поскольку 0 и 1 всегда являются корнями нашего уравнения, а ответы просят искать с двойки, то уменьшим мощность множества ответов на 2. Ответом будет $\frac {n — 2 — (2^{cnt} — 2)}{n — 2} = \frac {n — 2^{cnt}}{n — 2}$. Чтобы факторизовать число $n$, достаточно $O(\sqrt{n})$ операций, что и является сложностью алгоритма.

H. Heap Search

В псевдокоде поиска реализован обход «корень-левое-правое» с отсечением в корне: если текущее значение меньше искомого, то идти в потомков не следует, потому что они еще меньше. Переупорядочим числа в куче в порядке этого обхода. Тогда если искомого числа $k$ в куче нет, то наш обход посетит каждую вершину с большими значениями, чем $k$ и из них сделает еще по $2$ захода — влево и вправо. По индукции можно показать, что всего заходов будет $2 \cdot g + 1$, где $g$ — количество чисел в куче, больших, чем $k$.

Если же число $k$ в куче есть, то мы будем идти до его первого вхождения по массиву слева направо, заходя только в большие вершины и их непосредственных потомков. Значит, нам нужно для каждого числа быстро находить на префиксе количество чисел, больших, чем оно. Это можно делать с помощью какой-то структуры данных, например, дерева Фенвика. К ответу будем прибавлять $2 \cdot g$, если $k$ — левый потомок своего родителя или $2 \cdot g + 1$, если правый. Сложность алгоритма $O(n + m \cdot \log n)$, где $m$ — размер диапазона, в котором запускается HeapSearch.

I. Игра белко-бобров

Будем анализировать данную игру с помощью обхода в глубину. Назовем проигрышной позицию, в которой текущий игрок проигрывает, а выигрышной — ту, в которой выигрывает. Если мы в тупике, то мы точно проиграли. Если из нашей позиции есть ход в проигрышную (для соперника, который ходит следующим), то мы выиграли. Если же все ходы в выигрышную (для соперника), то мы проиграем за исключением случая, когда у текущей вершины нечетное количество потомков. Действительно, в выигрышную позицию никто ходить не будет, а значит каждый игрок будет перегрызать ребро графа. Если их нечетное количество, то тот, кто начнет грызть первым, тот и закончит последним. Сложность алгоритма $O(n)$.

J. За двумя зайцами

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

Сначала построим граф. Из истока кинем ребра пропускной способности 3 во все вершины, соответствующие еще не сыгранным матчам. Пропускная способность 3 будет означать, что в матче распределяются 3 очка в какой-то пропорции. Заметим, что матчей нашей команды среди них не будет, потому что мы уже выбрали все матчи, которые мы выиграем и проиграем. Из каждого матча кинем по ребру пропускной способности 3 в вершины, соответствующие тем командам, которые играют в этом матче. Это означает, что команда может набрать от 0 до 3 очков в каждом матче. Из каждой команды кинем в сток ребро пропускной способности, равной тому числу очков, которое имеет право набрать эта команда так, чтобы не догнать нашу команду. Поскольку мы уже распределили результаты нашей команды, то ее очки известны и очевидно, сколько имеет право набрать каждый соперник. Построив этот граф и пустив по нему поток Диницем, проверим, смогли ли мы распределить $3 \cdot g$ очков, где $g$ — количество еще не сыгранных матчей.

Теперь мы можем перебрать все возможные наборы сыгранных нашей командой матчей и для каждого проверить потоком, можем ли мы победить при таком выборе или нет. Заметим, что структура графа для всех наборов будет идентичной, различаться будут только пропускные способности ребер от команд к стоку. Всего различных наборов не больше, чем $2^{n-1}$.

Далее заметим, что поскольку нас интересует минимальный по количеству набор игр, можем воспользоваться бинарным поиском. Это дает нам целых 2 преимущества:
1) мы будем проверять множества не всех мощностей, а приблизительно половину из них;
2) если для какой-то мощности множества уже есть подходящий ответ, не нужно проверять все остальные, нам достаточно одного положительного исхода;
Распределим все возможные маски из диапазона $[0; 2^{n-1}-1]$ по векторам в зависимости от количества единичных бит и будем для текущего $k$ проверять только маски с $k$ единичными битами.

Теперь заметим еще одну вещь: для фиксированного $k$, если две маски различаются только двумя битами, то графы идентичны, за исключением пропускной способности двух ребер, соответствующих тем командам, с которыми мы играем в первом наборе и не играем во втором (и наоборот). Значит, если мы пихнули поток по графу, соответствующему какой-то маске, а потом перешли к почти такой же маске, мы имеем право не искать поток заново, а чуть поменять пропускные способности (не более чем на 3), пихнуть лишний поток величиной до 3 обычным DFS-ом назад в исток и затем пустить Диница, который всего лишь достроит недостающий поток.

Чтобы перебирать маски в указанном порядке, будем помещать их в векторы не в порядке возрастания, а в порядке построения кодов Грея. Тогда каждый запуск ДФС+Диница будет иметь сложность $O(n^2)$. Итоговая сложность алгоритма $O(2^{n-2} \cdot n^2)$, что укладывается в 4.5 секунды из 10, данных на задачу.

Related Images:

Тимус-марафон начинается!

Добрый день, уважаемые друзья!

С опозданием, но все же я решил начать тимус-марафон. Причиной для этого послужил тот факт, что у наших команд теоретическая подготовка стала опережать практические навыки. Сбалансировать это соотношение можно только кодингом большого количества не очень сложных задач, а лучший архив для этих целей, чем acm.timus.ru, трудно представить.

Посему настоятельно прошу всех товарищей, которым не безразличны их результаты на предстоящих соревнованиях, зарегистрироваться на acm.timus.ru и сообщить мне свой никнейм сообщением под этим постом. +к карме, если ваш никнем будет содержать подстроку «ONU» (без кавычек).

Правила тимус-марафона:

1) Итоги подводятся каждый месяц, 1-го числа.

2) Всеобщего восхищения удостаиваются два человека: лидер в общем зачете (тот у кого больше всего сданных задач за все время) и лидер месяца (добившийся наибольшего прогресса за месяц).

3) Задачи рекомендую сдавать, отсортировав их по сложности — это вполне подходит для наших целей.

4) Первое подведение итогов назначено на 1 мая 2019.

Да пребудет с вами сила и терпение!

Related Images:

[Базовый олимпиадный курс] Занятие 4. Остовные деревья

Добрый день, уважаемые друзья!

В преддверие 1/8 чемпионата Мира ACM ICPC мы возобновляем наше вещание темой остовных деревьев. Андрей Станкевич милостиво явит свой голос и образ по этой ссылке, а задачи соответствующей темы возникнут здесь.

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

Related Images:

[Базовый олимпиадный курс] Занятие 3. Поиск путей на графах

Добрый день, дорогие, друзья!

Сегодня предметом нашего изучения станут графы на путях пути на графах. С целью входа в тему Вам следует до 9 января посмотреть лекцию 1, а с целью дальнейшего ее развития до 12 января посмотреть лекцию 2, а также прочитать и понять статью об алгоритме Флойда.  Далее 10 и 13 января пишем по одному тренировочному контесту. Сначала этот, затем этот. Контесты пишем в виртуальном режиме. Разумеется, кто будет готов раньше, может написать их раньше.

И да пребудет с Вами Сила!

Related Images:

[Базовый олимпиадный курс] Занятие 2. Динамическое программирование

Добрый день, уважаемые друзья!

На этот раз нашей темой будет динамическое программирование. Тема очень важная и обширная, поэтому одной лекцией Андрея Станкевича не исчерпывается. Однако, в для начала вам следует посмотреть его лекцию на youtube до воскресенья, а в воскресенье, 2 декабря, решить в виртуальном режиме следующий трехчасовой контест. Убедительная просьба условия до начала виртуального контеста не читать — хороших тренировок не так много и портить их себе не стоит.

Также напоминаю про соревнование Proggy-Baggy в субботу, 1 декабря.

Всем неравнодушным настоятельно советую Educational Codeforces Round 55. Контесты этой серии вообще пропускать не стоит, что напрямую следует из их названия.

Также напоминаю про необходимость добивания задач прошедших соревнований. Пока всего два студента занимаются дорешиванием первого контеста нашей тренировочной серии. Присоединяйтесь!

Related Images:

[Базовый олимпиадный курс] Занятие 1. Сложность алгоритмов, сортировка и поиск

Добрый день, уважаемые друзья!

Начиная с этого дня, в рамках подготовки к олимпиадам открывается курс алгоритмического самоспасения. На данный момент к нему присоединились 6 человек, однако количество мест не ограничено. Все определяется вашим желанием достичь успеха в олимпиадном программировании и приложить к этому максимум своих персональных усилий.

Каждый участник курса должен создать аккаунт на сайте codeforces.com, где будут проходить подготовительные соревнования в рамках специально созданной группы. Подавайте заявки на вступление прямо на сайте!

В качестве первого задания олимпийцам следует принять участие в завтрашнем контесте, прочитать разбор и дорешать нерешенные задачи. Также до воскресенья следует посмотреть две лекции Андрея Станкевича 1, 2, по темам которых в нашей группе будет проведен 3-часовой индивидуальный контест в воскресенье, 25 ноября в 12:00. Разбор задач будет опубликован под этом постом.

В качестве дополнительного задания следует зарегистрировать свою команду на онсайт-контест Proggy-Baggy, намеченный на субботу, 1 декабря, обнаружить его место проведения — офис Data-Art (предположительно в комплексе стадиона «Черноморец») и принять в нем активное участие.

Также следует зарегистрироваться на сайте topcoder.com и участвовать во всех личных контестах, проводимых там и на codeforces по мере их появления.

С 1 декабря объявляется бессрочный timus-марафон — личное соревнование по количеству сданных задач на платформе acm.timus.ru, промежуточные итоги которого будут проводиться ежемесячно. Для участия в нем следует создать аккаунт на тимусе и сообщить мне имя пользователя. Победителям, как водится, почет, слава и уважение.

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

Related Images: