320 likes | 552 Views
3 февраля 2014 года. Задача 5 . «Светофоры». Задача 5. « Светофоры ». Разбор задачи – Егор Беликов. Задача 5. «Светофоры». Постановка задачи.
E N D
Задача 5. «Светофоры» • Задача 5.«Светофоры» Разбор задачи – Егор Беликов
Задача 5. «Светофоры» Постановка задачи • Электрокар едет по дороге, на ней два светофора, которые синхронно переключаются: сначала a минутзеленым, потом b минут красным. Расстояние между светофорами равно x. • Вычислить, с какой максимальной скоростью может двигаться электрокар, чтобы проехать оба светофора на зелёный свет.Скорость автомобиля не больше 1000.
Задача 5. «Светофоры» Частичное решение • За частичное решение для тестов, в которых ответ целочисленный, оценивались в 50 баллов. • Решим задачу: «У автомобиля скорость v. Может ли он проехать оба светофора на зелёный?»
Задача 5. «Светофоры» Частичное решение • Рассмотрим два электрокара A и Б, двигающихся со скоростью v. • Пусть электрокар А проезжает первый светофор в момент включения зелёного сигнала, а электрокар Б – в момент выключения (на aминут позже А). • Если хотя бы один из них проезжает второй светофор на зеленый свет, то ответ очевиден. • Если же А и Б подъезжают ко второму светофору на красный свет, но никакой другой электрокар между ними не сможет проехать на зеленый (потому что между электрокарами ровно aминут).
Задача 5. «Светофоры» Частичное решение • Таким образом, нам нужно понять, может ли электрокар проехать на зеленый свет с заданной скоростью v. • Зная расстояние между светофорами xи их период работы ,мы можем воспользоваться формулойдля электрокара А и для электрокара Б (где /обозначает целочисленное деление, % - взятие остатка от деления). • Осталось перебрать все числа до 1000 и вывести ответ.
Задача 5. «Светофоры» 4 Решение В общем случае ответ не всегда будет целочисленным. Рассмотрим те же электрокары А и Б, двигающиеся со скоростью 1000. Если один из них проезжает второй светофор на зелёный, то ответ очевиден. В противном случае нам выгоднее всего уменьшить скорость электрокара Б ровно на столько, чтобы он проехал второй светофор в момент включения зелёного сигнала. Тогда он должен двигаться на дольше. Ответом будет его скорость, равная, где – время движения между светофорами со скоростью 1000.
Задача 6. «Кондиционеры» Задача 6. «Кондиционеры» • Разбор задачи – Егор Беликов
Задача 6. «Кондиционеры» Постановка задачи В каждый из nклассов нужно поставить по кондиционеру, в класс с номером iнужно поставить кондиционер мощностью не меньшеai. Есть список из m кондиционеров, которые можно закупить, даны их стоимости. Нужно закупить кондиционеры по наименьшей стоимости.
Задача 6. «Кондиционеры» Частичное решение Можно было для каждого класса перебрать все кондиционеры и выбрать с подходящей мощностью и минимальной стоимостью. Асимптотическая сложность – O(nm).
Задача 6. «Кондиционеры» Решение Отсортируем кондиционеры по стоимости, а в случае равной стоимости – по мощности. Последовательно просматривая их, можно удалить те кондиционеры, у которых мощность не больше, а стоимость больше либо равна. Получим массив, в котором кондиционеры отсортированы и по стоимости, и по мощности.
Задача 6. «Кондиционеры» Решение • Теперь отсортируем классы по требуемой мощности. Пройдем по массиву классов и массиву кондиционеров методом двух указателей – один указатель на класс, другой – на кондиционер. При увеличении требуемой мощности указатель на кондиционер будет только расти. • Асимптотическая сложность – O(n log n + m log m).
Задача 6. «Кондиционеры» На что стоило обратить внимание? • На размер массивов • На время работы сортировки • На рандомизацию сортировки
Задача 7. «Конфеты» Задача 7. «Конфеты» Разбор – Хисматуллин Тимур
Задача 7. «Конфеты» Очень простая задача Для начала научимся решать более простые задачи, например, задачу не для параллелепипеда, а для отрезка. То есть, пусть у нас есть отрезок максимальной длины x (x = N), и «коробки» (отрезки) длины a, тогда максимальным числом коробок будет число (x // a), где “//” – целочисленное деление(div). Иначе говоря, мы запихиваем как можно больше отрезков длины aв большой отрезок N
Задача 7. «Конфеты» Простая задача Теперь решим нашу задачу для прямоугольника (то есть, будем считать, что у нас все коробки плоские). Пусть a = b = 1. То есть, у нас все коробки квадратные c длиной один. Тогда самым лучшим ответом для нашей задачи будет квадрат с длиной N/2(еслиN нечетное, то стороны будут N/2 – 0.5 и N/2 + 0.5). Действительно, пусть x = N/2+t, y = N/2-t. Тогда xy = (N/2-t)(N/2+t) = (N/2)2 – t2 < (N/2)2при любых t.
Задача 7. «Конфеты» Не очень простая задача Теперь пусть стороны коробки любые (но по-прежнему, коробки плоские). Поймем, длина нашего большого прямоугольника должна быть кратна a, а ширина - b, и если это не так, то можно сократить до кратных длин, и количество коробок не изменится.
Задача 7. «Конфеты» Не очень простая задача Тогда длина нашего прямоугольника будет иметь размер ax, а ширина – by, при этом количество коробок при такой длине и ширине xy. Можно предположить, что axи by близки к N/2. Тогда возьмем изначальные x0 = N // 2a и y0 = N // 2b. Заметим, что ax0 > N/2 - a и by0 > N/2 - b (так как мы вместили в N/2 максимальное количество “a-шек”). Поэтому ax0*by0>(N/2-a)(N/2-b) > (N/2)2 - (a+b)(N/2)
Задача 7. «Конфеты» Не очень простая задача Рассмотрим другие значения длины и ширины. Пусть ax = N/2 – t, а by = N/2 + t. Тогда ax*by = (N/2)2 – t2. И если t2 ≥ (a+b)(N/2), то количество коробок будет меньше или равно. Значит, t2 < (a+b)(N/2). Рассмотрим, при каких значениях t результат может быть лучше. Пусть t = a*dx= b*dy и a ≥ b. Из предыдущего абзаца мы узнали, что t2 <(a+b)(N/2), илиt2 < 2a(N/2) = aN => (a*dx)2< aN => dx < sqrt(N/a) < sqrt(N).
Задача 7. «Конфеты» Решение не очень простой задачи Это значит, что ax и by должны принимать не больше sqrt(N) других значений, чтобы количество коробок было не меньше, чем при ax0и by0. То есть, для решения нашей задачи нам можно зафиксировать какую-нибудь ось(длину и ширину), перебрать O(sqrt(N)) значений, а значение по другой оси вычислить как N-x. Перебрав эти значения и высчитывая при этом размеры коробки, можно выбрать лучший вариант и получить ответ.
Задача 7. «Конфеты» Решение не очень простой задачи В итоге, мы научились решать задачу на плоскости за O(sqrt(N)), и это значит, что мы уже можем решить нашу задачу в пространстве на 60(а на деле больше) баллов, перебрав высоту коробки за O(N).
Задача 7. «Конфеты» Решение задачи Чтобы решить задачу на полный балл, нужно привести точно такие же рассуждения, как и для плоскости, то есть считать, что лучший ответ лежит в границе cbrt(N) около N/3(так как лучший ответ для a = b = c = 1 является кубом со сторонами N/3). То есть, для решения задачи на полный балл необходимо зафиксировать какую-нибудь ось и перебрать cbrt(N) значений на ней. Далее необходимо решить эту задачу в плоскости(осталось 2 оси). Итоговая сложность алгоритма будет O(N2/3). sqrt – квадратный корень из числа cbrt– кубический корень из числа
Задача 7. «Конфеты» Обобщение С учетом сказанного решение исходной задачи будет следующим. 1. Берем в качестве первого приближения x = N // 3a, y = N // 3b, z = N // 3c 2. Переберем все перестановки a, b и c. 3. Переберем x в интервале от n // 3a – cbrt(N) до n // 3a + cbrt(N) 4. Переберем y в интервале от (n – ax) // (2b) – cbrt(N) до (n – ax) // (2b) + cbrt(N) 5. Получаем z = (n – ax – by) // c и проверяем, стало ли произведение больше текущего.
Задача 7. «Конфеты» Заметка Заметим, что количество коробок конфет, определяемое произведением размеров коробки, может быть порядка 1027, то есть, превышать максимальное значение целого 64-битного типа данных. Для того, чтобы избежать длинной арифметики при сравнении перебираемых вариантов, можно вместо неравенства вида x1y1z1 > x2y2z2 использовать неравенство x1y1z1 - x2y2z2 > 0. Если разность не превышает 263, то неравенство с переполнением будет определено верно. Также можно использовать вещественный тип с расширенной точностью.
Задача 8. «Волонтеры» Задача 8. «Волонтеры» Разбор – Кузьмичев Дмитрий
Задача 8. «Волонтеры» Решение • Заметим, что для каждого члена жюри множество волонтеров, ему подчиненных, образует отрезок. Это следует из алгоритма, осписанного в условии задачи (важен тот факт, что член жюри становится в ряд вместо того отрезка людей, который он выбрал). Аналогичное наблюдение верно, конечно, и для членов оргкомитета. • Первая часть решения - это найти такие отрезки для всех членов жюри. Рассмотрим граф, в котором у нас будут ориентированные ребра (a,b), где a - это прямой начальник b. Легко видеть, что этот граф будет без циклов.
Задача 8. «Волонтеры» Поиск в глубину (dfs) • С помощью обхода в глубину (dfs) теперь можем вычислить все отрезки за суммарное время O(m). • Сначала запустимся из вершины m, которая соответствует председателю жюри. • Пусть текущая вершина v. Для начала запустим dfs от всех ее потомков. • Пусть [x1;x2] - это искомый отрезок для v. Пройдемся по всем потомкам, пусть сейчас рассматривается потомок u с отрезком [y1;y2] (он уже известен, потому что от u уже был вызван dfs). • Тогда, если y2 > x2, то x2 теперь станет y2. Аналогично, если y1 < x1, то x1 теперь станет y1. Это соответствует тому, что все подчиненные u являются также подчиненными v. • Также, у нас есть волонтеры, подчиненные непосредственно v. Если волонтер имеет номер w, то его отрезок - это просто [w;w], и для него делаем то же самое, просто полагаем y1 = y2 = w
Задача 8. «Волонтеры» Нахождение ответа • Итак, отрезки найдены для членов жюри. Абсолютно аналогично находим их для членов оргкомитетаВторая часть решения - это нахождение ответа на вопрос задачи. Пусть есть A - член жюри и B - член оргкомитета, тогда если у A и B есть общий подчиненный волонтер, то это просто означает, что соответствующие им отрезки пересекаются • Т.е. задача свелась к следующей: есть отрезки двух типов, найти количество пар <A, B>, где A - отрезок первого типа, B - второго, A и B пересекаются • Это можно сделать следующим образом. Введем события вида: <x, тип>, x - координата(номер волонтера), тип означает следующее: • 1 - начался отрезок второго типа • 2 - начался отрезок первого типа • 3 - кончился отрезок первого типа • 4 - кончился отрезок второго типа • Посортируем эти события просто как пары из двух чисел
Задача 8. «Волонтеры» Нахождение ответа • Наша цель будет для каждого отрезка первого типа найти количество отрезков второго типа, с которыми он пересекается. • Введем следующие обозначения: cnt - счетчик числа всех отрезков 2-го типа, которые начались до текущего момента (и могли закончиться), active - количество "активных" отрезков 2-го типа на данных момент, т.е. еще не законченных.
Задача 8. «Волонтеры» Нахождение ответа • С учетом этих обозначений, пусть у нас есть отрезок первого типа [x1;x2]. Тогда с ним пересекаются: • Во-первых, все отрезки 2-го типа, у которых начало будет лежать в (x1;x2]. Чтобы вычислить количество таких отрезков, нужно из значения cnt в x2 вычесть значение cnt в x1. • Во-вторых, все отрезки 2-го типа, у которых начало <= x1, конец >= x1. Это количество равно значению active в x1. • Идем по событиям по порядку, поддерживая cnt и active. Пусть answer – ответ на задачу, list содержит все события в уже отсортированном виде. Тогда answer может быть вычислен с помощью следующего фрагмента кода
Задача 8. «Волонтеры» Нахождение ответа for(int it = 0; it < list.size(); it++) { switch(list[it].second) { case 1: { active++; cnt++; break; } case 2: { answer -= cnt; answer += active; break; }
Задача 8. «Волонтеры» Нахождение ответа case3: { answer += cnt; break; } case 4: { active--; break; } } } В зависимости от типа события делаем следующее: 1 - начался отрезок второго типа, увеличиваем cnt и answer 2 - начался отрезок первого типа, к ответу прибавится active и вычтется cnt 3 - кончился отрезок первого типа, к ответу прибавится cnt 4 - кончился отрезок второго типа, active уменьшится