3 февраля 2014 года

Post on 11-Jan-2016

60 views 1 download

description

3 февраля 2014 года. Задача 5 . «Светофоры». Задача 5. « Светофоры ». Разбор задачи – Егор Беликов. Задача 5. «Светофоры». Постановка задачи. - PowerPoint PPT Presentation

Transcript of 3 февраля 2014 года

Региональный этап всероссийской олимпиады

школьников по информатике2 тур

3 февраля 2014 года

Разбор задачи – Егор Беликов

Задача 5. «Светофоры»

Задача 5. «Светофоры»

• Электрокар едет по дороге, на ней два светофора, которые синхронно переключаются: сначала a минут зеленым, потом b минут красным. Расстояние между светофорами равно x.

• Вычислить, с какой максимальной скоростью может двигаться электрокар, чтобы проехать оба светофора на зелёный свет. Скорость автомобиля не больше 1000.

Постановка задачи

Задача 5. «Светофоры»

• За частичное решение для тестов, в которых ответ целочисленный, оценивались в 50 баллов.

• Решим задачу: «У автомобиля скорость v. Может ли он проехать оба светофора на зелёный?»

Частичное решение

Задача 5. «Светофоры»

Частичное решение

Задача 5. «Светофоры»

• Рассмотрим два электрокара A и Б, двигающихся со скоростью v.

• Пусть электрокар А проезжает первый светофор в момент включения зелёного сигнала, а электрокар Б – в момент выключения (на a минут позже А).

• Если хотя бы один из них проезжает второй светофор на зеленый свет, то ответ очевиден.

• Если же А и Б подъезжают ко второму светофору на красный свет, но никакой другой электрокар между ними не сможет проехать на зеленый (потому что между электрокарами ровно a минут).

Частичное решение

Задача 5. «Светофоры»

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

• Зная расстояние между светофорами x и их период работы , мы можем воспользоваться формулой для электрокара А и для электрокара Б (где / обозначает целочисленное деление, % - взятие остатка от деления).

• Осталось перебрать все числа до 1000 и вывести ответ.

4

В общем случае ответ не всегда будет целочисленным.

Рассмотрим те же электрокары А и Б, двигающиеся со скоростью 1000. Если один из них проезжает второй светофор на зелёный, то ответ очевиден.

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

Тогда он должен двигаться на

дольше.

Ответом будет его скорость, равная , где – время движения между светофорами со скоростью 1000.

Решение

Задача 5. «Светофоры»

• Разбор задачи – Егор Беликов

Задача 6. «Кондиционеры»

Задача 6. «Кондиционеры»

В каждый из n классов нужно поставить по кондиционеру, в класс с номером i нужно поставить кондиционер мощностью не меньше ai. Есть список из m кондиционеров, которые можно закупить, даны их стоимости.

Нужно закупить кондиционеры по наименьшей стоимости.

Постановка задачи

Задача 6. «Кондиционеры»

Можно было для каждого класса перебрать все кондиционеры и выбрать с подходящей мощностью и минимальной стоимостью. Асимптотическая сложность – O(nm).

Частичное решение

Задача 6. «Кондиционеры»

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

Решение

Задача 6. «Кондиционеры»

• Теперь отсортируем классы по требуемой мощности. Пройдем по массиву классов и массиву кондиционеров методом двух указателей – один указатель на класс, другой – на кондиционер. При увеличении требуемой мощности указатель на кондиционер будет только расти.

• Асимптотическая сложность –

O(n log n + m log m).

Решение

Задача 6. «Кондиционеры»

oНа размер массивов

oНа время работы сортировки

oНа рандомизацию сортировки

На что стоило обратить внимание?

Задача 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. Легко видеть, что этот граф будет без циклов.

Поиск в глубину (dfs)

Задача 8. «Волонтеры»

• С помощью обхода в глубину (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. «Волонтеры»

case 3:{

answer += cnt;break;

}case 4:

{active--;break;

}}

}В зависимости от типа события делаем следующее: 1 - начался отрезок второго типа, увеличиваем cnt и answer 2 - начался отрезок первого типа, к ответу прибавится active и вычтется cnt 3 - кончился отрезок первого типа, к ответу прибавится cnt 4 - кончился отрезок второго типа, active уменьшится