Краткий разбор моих решений Andrey Mokhov Contest #4

7

Продолжаю начинание…

Внимание! В комментариях можно прочесть авторский и альтернативные подходы к решению задач.

Задачи, результаты.

Спасибо Андрею Мохову за очередной красивый контест :)

Задача A. Agreement

Если немного формализовать задачу, то она будет звучать так:

Дано логическое выражение вида (x1 | ~x1) & (x2 | ~x1) & (x2 | x3) & ,.., где xi – это глаголы в исходной задаче. Требуется определить, существует ли такое множество значений xi, при которых данное выражение истинно.

Данная задача известна как 2-SAT. Основная идея решения: построим ориентированный граф, вершинами которого будут xi и ~xi. Пусть в логическом выражении существует дизъюнкция (a | b), тогда в графе должны быть ребра ~a -> b, ~b -> a, что означает «если ~a – истина, то b тоже истина, а если ~b истина, то a – истина». Ясно, что необходимым условием существования решения является отсутствие в этом графе цикла, в который одновременно входят c и ~c. Другими словами, c и ~c не должны одновременно находиться в одной сильно-связанной компоненте графа. Можно доказать, что это условие является и достаточным. Таким образом, решение задачи сводится к нахождению сильно-связанных компонент графа, что делается обходом в глубину за линейное время.

Задача C. Collect the coins

Попробуем смоделировать последние шаги удачной последовательности перемещений. Пусть всего монет M, а шагов K.

  • после K-го шага: одна коробка с M монетами;
  • после K-1-го шага: M / 2, M / 2;
  • после K-2-го шага: (M / 4, M / 4, M / 2) или (3M / 4 и M / 4);

Становится ясно, что количество монет в любой коробке всегда должно иметь вид pM / q, где q – степень двойки, а p – нечетное.

Вычислим для каждого ai значения pi и qi. Очевидно, что перемещать монеты нужно между такими i и j, что qi = qj. Пусть pi > pj, тогда:

pi -= pj;
pj += pj.

Понятно, что в результате данной операции pi и pj становятся четными, что позволяет сократить их как минимум на 2, не забывая про qi и qj. Повторяя такую операцию, пока возможно, получаем решение задачи. Оценка количества шагов: для каждого значения знаменателя не может быть больше N / 2 пар коробок. Количество различных значений знаменателей – log N. Количество шагов – N log N / 2, что гораздо меньше требуемых 10000.

Задача D. Disconnect the network

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

Задача E. Efficient sorting

Представим перестановку в виде графа с N вершинами и ребрами i -> a[i]. Можно доказать, что этот граф представляет собой набор циклов. Следовательно, если мы возьмем какое-то a[i] и поставим его на свое место, а с числом, которое стояло на месте a[i] повторим то же самое, то мы пойдем по циклу и в один прекрасный момент закончим последовательность перестановок, обойдя весь цикл. Ясно, что количество перестановок в одном цикле на единицу меньше количества вершин в этом цикле. Таким образом, отняв от количества вершин количество связанных компонент, получим ответ.

Задача F. Full-length mirror

Внимательное рассмотрение чертежа в течение нескольких секунд дает вполне очевидный ответ – половина от высоты Данила.

Задача G. Good fraction

Как всегда, когда не понятно оптимальное решение и ограничения не намного превосходят те, при которых задача решалась бы «в лоб», попробуем эвристики. Лобовое решение:

  • переберем все N от 1 до 10^D, где D – количество цифр после запятой в x;
  • для каждого N вычислим соответствующее G;
  • если G / N укладывается в интервал [x - 0.5 * 10 ^ (-D + 1), x + 0.5 * 10 ^ (-D + 1)), то ответ найден.

Недостаток данного решения - D может быть до 8, а 10^8 операций с 64-битными целыми это довольно долго.

Теперь оптимизации:

  • очевидно, что перебирать можно не до 10^D, а до D / gcd(x, 10^D);
  • если потестить значения, близкие к нулю или к единице, то можно заметить, что именно на них программа работает самое большое время. Правильное решение - таблица, например, для первых и последних 50 значений x :) ;
  • вычисление и проверку G надо делать в целых числах, используя как можно меньше операций деления.

Такие нехитрые оптимизации приводят перебор к Accepted.

Задача H. Hungry? Go eat!

Классическое название задачи - задача о двух станках. Решает ее алгоритм Джонсона. Выпишем все C[k] и E[k] в одну последовательность A и будем повторять следующие действия, пока это последовательность не опустеет:

  • возьмем минимальное число из A;
  • если взятое число исходно было из C, то соответствующее блюдо добавим в очередь Q;
  • если взятое число исходно было из E, то соответствующее блюдо добавим в стек S.

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

TopCoder SRM 401

0

Вот и прошел очередной «Great Ratings Fall SRM». Относительная очевидность первых двух задач, не помешала сильно потормозить на первой и допустить баг во второй… В первой требовалось написать простую трехцикловую динамику. Во второй, составив очевидную систему уравнений, достаточно сложить квадраты первых двух из них, в результате чего получится квадратное уравнение. Дальше оставалось лишь рассмотреть частные случаи.

Результат СРМ в очередной раз подтвердил выражение «все хорошо в меру» – параллельное писание СРМ и просмотр интересного фильма до добра не доведут :(

TopCoder SRM 400

0

Вот и прошел очередной срм, который я впервые за последнее время написал более-менее нормально. Ключевым шагом было не поддаться депрессии после Coding Phase, когда я был примерно 15-м в комнате, и написать тест, валящий жадные решения. В результате 6 удачных челленджей и резкий скачок на 1-е место в комнате. Правда радость была скоро уничтожена глупым багом в первой задаче, которую, почему-то никто не решился челленджить (наверное, красный цвет сделал свое дело :) ). Но после систем теста я опустился всего на 2 места, и таким образом получаю немного денег и некоторую прибавку к рейтингу. Но в целом срм подтвердил мою «неудачливую» натуру – если бы первая не упала, я был бы 3-м в дивизионе :(

Фотографии с KBTU Open 2008

1

Закрытие

Закрытие.

 

Наша команда: я и Жомарт Садыков

Наша команда: я, Жомарт Садыков (Сергей к тому времени уже ушел) и ретро-телефоны от АЛСИ.

 

Команда FIZMAT 2: Ли Владимир, Есмуханов Даурен, Далиев Асет

Фуад Гаджиев, команда FIZMAT 2 и ваучеры от АЛСИ.

 

Вроде команда СДУ :)

Фуад Гаджиев, конверт с деньгами и команда, насколько помню, СДУ.

Краткий разбор задач KRSU Open Contest 2008

9

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

Задачи, результаты.

Спасибо Улану Дегенбаеву и Андрею Мохову за интересный контест.

Problem A. Absolute Equation

Ключевая идея решения: весь интервал от -10^8 до 10^8 можно разбить на подинтервалы, внутри которых каждое из подвыражений уравнения (x, |x| + a, x + b) имеет постоянный знак и не равно нулю (x’ы, при которых какое-то из подвыражений равно 0 будут являться границами этих интервалов). Точки, являющихся границами интервалов это:

  1. -10^8, 0, 10^8;
  2. a, -a, при a < 0;
  3. -b.

Теперь, если взять интервал (l, r), то знак каждого из выражений строго определяется любым x’ом из этого интервала. Получив знак каждого выражения, избавляемся от модуля и решаем получившееся линейное уравнение, не забывая проверить, что ответ входит в нужный интервал.

Есть еще 2 частных случая:

  1. x’ы, равные границам интервалов надо проверить отдельно;
  2. при некоторых обстоятельствах интервал может целиком удовлетворять уравнению. Это легко проверить, подставив 2 разных x из этого интервала в уравнение. Если оба подошли, значит подойдет и весь интервал.

Problem B. Box packing

Очевидная интуитивная догадка:

  1. положим все коробки в приоритетную очередь (приоритет – время прибытия, чем оно более раннее, тем приоритет выше);
  2. возьмем две коробки с наиболее ранним временем прибытия, удалим их из очереди и упакуем, получив новую коробку с временем прибытия max(t1, t2) + k, которую положим обратно в очередь;
  3. повторяем пока в очереди не останется одна коробка, время ее прибытия и будет являтся ответом.

Problem C. Check Solution

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

Problem D. Deficient Memory

У нас мало памяти, но много времени. Посчитаем сначала количество чисел от 0 до 250000 – 1, затем от 250000 до 500000 – 1, от 500000 до 750000 – 1 и от 750000 до 1000000, встречающихся в обоих последовательностях. Это можно сделать, следующим образом:

  1. генерируем первую последовательность и каждое число (если оно лежит в нужном интервале) отмечаем в битовом массиве;
  2. генерируем вторую последовательность и если встречается число, отмеченное в битовом массиве, то увеличиваем результат на единицу, а из битового массива снимаем отметку, соответствующую этому числу.

Легко заметить, что для данного решения требуется не более 250000 / 8 ~32K памяти.

Problem E. Extreme point

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

  1. посчитаем сумму расстояний (s) до самой левой точки;
  2. пойдем по всем координатам от самой левой до самой правой точки, поддерживая количество точек не правее текущей координаты (l). При этом, когда переходим от координаты x к x + 1, то пересчитываем s по следующей формуле: s = s – (n – l) + l. Таким образом для каждой координаты мы будем знать сумму расстояний от нее до всех точек, и попутно выбирая минимум получим ответ.

Короткий разбор задач с KBTU Open 2008

3

Задачи KBTU Open 2008 (спасибо Герману Ильину за предоставление электронных вариантов условий).

Задача A. Computer Networks

Условие задачи сводится к нахождению минимального реберного разреза между любыми двумя вершинами в графе. Как известно величина реберного разреза между вершинами s и t численно равна величине максимального потока между этими же вершинами. Простой перебор всех пар вершин и нахождение между каждой парой вершин этого самого потока не уложится по времени. Для решения задачи достаточно заметить (доказать, интуитивно предположить :) ), что перебирать надо не все пары вершин, а только пары (1, i) (естественно, вместо вершины 1 можно взять любую другую).

Задача B. Contest

Динамика по двум параметрам. Пусть d[i, j] – количество различных «ranklist» для i участников распределенных по j местам (не забываем, что несколько участников могут занимать одно место). Тогда при j > i d[i, j] = 0, а в остальных случаях d[i, j] = (d[i - 1, j] + d[i - 1, j - 1]) * j.

Задача C. Counter Strike

Задача на «идею». Переберем все пары оружия и количество патронов, которые мы можем купить. Пусть a1, a2 – «damage» текущих видов оружия, а b1, b2 – соответствующие количества патронов. Надо сосчитать для всех возможных a1, a2, b1, b2, сколько максимум врагов мы сможем уложить. Теперь «идея» (одна из возможных): возьмем какое-то количество выстрелов одного оружия и найдем, сколько необходимо выстрелов другого оружия в дополнение к ним, чтобы уложить одного врага. Уложим таким образом столько врагов, сколько сможем. Для оставшегося количества патронов рекурсивно повторим процедуру. Вот и все (доказательства не спрашивать :) ).

Задача D. Fatboy

Задача сводилась к нахождению наибольшей общей подпоследовательности трех последовательностей так. Делается стандартной динамикой по трем параметрам: d[i, j, k] – длина наибольшей общей подпоследовательности префиксов строк длиной i, j, k.

Задача E. Super Heroes

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

Задача G. Points

Известно, что удвоенная площадь треугольника, вершины которого имеют целочисленные координаты – целая. Таким образом надо посчитать, сколько получается треугольников с четной площадью. Если расписать площадь как векторное произведение двух векторов, то можно заметить, что ее четность зависит только от четности координат векторов, которые в свою очередь зависят только от четности координат вершин. Поэтому все вершины можно «сложить» в квадрат (0, 0) – (1, 0) – (1, 1) – (0, 1) (при этом несколько вершин могут «сложиться» в одну), а дальше – тривиальный перебор или формула.

Задача H. Sequence

Динамика по N. Пусть f[i, j] – количество хороших последовательностей длины i, оканчивающихся на j, где j – это 0 или 1. Тогда:
f[i, 0] = f[i - 1, 0] + f[i - 1, 1];
f[i, 1] = f[i - 1, 1] + f[i - 1, 0] – f[i - 2, 1] + f[i - 3, 1].
Опять же, здесь не надо хранить само количество, – достаточно его четности.

Обо всем понемногу…

0

Давно уже не писал – то не было времени, то желания, но вот решился наконец.

Республиканскую студенческую олимпиаду наша команда (я и Сергей Склонин) все-таки выиграла. В первом туре я был первым, а Сергей – вторым, во-втором – наоборот. За первое командное место нам дали принтер… один :( За первое индивидуальное место мне дали бумажку, это подтверждающую. Но в общем все-таки получилось довольно неплохо – олимпиада заставила решить задачу с NEERC, которую в домашних условиях решать было лениво :)

Также, прошла III-V этапы Республиканской олимпиады школьников по информатике. Задачи, составленные мной, на удивление, оказались не очень простыми, что показали 1-й и, особенно, 2-й тур V этапа, проходившего в Павлодаре. В Павлодаре нас устроили довольно неплохо, хотя с первого взгляда зона отдыха Энергетик походила именно на зону :) Главный положительный момент поездки – познакомился с ребятами из КБТУ и научился играть в русский бильярд.

Через день после возвращения из Павлодара состоялся Открытый чемпионат КБТУ, на котором мы участвовали экспериментальной командой – я, Сергей и Жомарт Садыков – золотой призер IOI прошлого года. Не оправдав надежды организаторов, мы решили все задачи за 4 часа и получили вторую порцию пиццы :) А на награждении симпатичные девушки из Алси подарили нам ретро-телефоны и свои визитки.

Ретро-телефон от Алси

Ретро-телефон от Алси

Республиканская студенческая олимпиада, I тур

0

Практически только что закончился I тур олимпиады в КарГТУ. На нее собралось, как сказали на открытии, 27 команд из 20 ВУЗов Казахстана. Сразу хочется отметить плюсы и минусы:

+ приветливые организаторы/дежурные, симпатичные девушки :) ;
+ быстрая регистрация;
+ удобное расположение компьютерных классов;
+ без проблем получены призы за проходившую незадолго до этого Дистанционную олимпиаду :) ;

- места в гостинице не были забронированы организаторами, хотя они зачем-то справлялись, будем ли мы жить в предложенной ими же гостинице;
- не продумано питание участников – в предложенном кафе заказ ждали около часа, а потом двум из нас сказали, что того, что они заказали нет, а все остальное закончилось;
- отсутствие пробного тура или хотя бы его подобия – как следствие, даже обещанный Visual C++ 6.0 не работал и пришлось писать на Delphi :( ;
- неполные условия задач и неправильный тип задач для олимпиады по программированию;
- ручная проверка задач – результаты обещали к 18.00, но, по слухам, в прошлом году проверка затягивалась до ночи.

Вот, пока все.

Результаты III Международной дистанционной олимпиады по информатике

0

Сегодня появились долгожданные результаты. Оказалось, что я, как и некто Коробов Алексей из КарГТУ, стали победителями среди студентов, набрав максимальное количество баллов. Теперь надо бы забрать из Караганды заслуженные 6 тысяч тенге :)

Определены финалисты TCHS 2008

0

Список здесь. Поздравляем Армана Есенаманова (army), ставшего единственным представителем Казахстана.

Вверх