Сегодня прошла вторая олимпиада из цикла интернет-олимпиад, проводимого ИТМО.
Предлагаю после завершения усложненной номинации обсудить здесь задачи (примерно через 20 минут).
P.S. По возможности, кто-нибудь, расскажите решения задач.
№ | Пользователь | Рейтинг |
---|---|---|
1 | tourist | 3993 |
2 | jiangly | 3743 |
3 | orzdevinwang | 3707 |
4 | Radewoosh | 3627 |
5 | jqdai0815 | 3620 |
6 | Benq | 3564 |
7 | Kevin114514 | 3443 |
8 | ksun48 | 3434 |
9 | Rewinding | 3397 |
10 | Um_nik | 3396 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 167 |
2 | Um_nik | 163 |
3 | maomao90 | 162 |
3 | atcoder_official | 162 |
5 | adamant | 159 |
6 | -is-this-fft- | 158 |
7 | awoo | 157 |
8 | TheScrasse | 154 |
9 | Dominater069 | 153 |
9 | nor | 153 |
Сегодня прошла вторая олимпиада из цикла интернет-олимпиад, проводимого ИТМО.
Название |
---|
А если перебирать sinx. И каждый раз строить две линии и проверять.
Я сам не пробовал, но была идея.
Интересует не идея, а решение, проходящее тесты.
Сами перебирали угол с точностью до 10-5 и проводили две прямые, но получали WA33
Чтобы отличить вектор a = (5e8 - 1, 5e8 - 2) от вектора b = (5e8 - 2, 5e8 - 3) нужно тыкнуться в интервал шириной . Вы не успеете проверить столько интервалов, да и точности стандартных типов близко не хватает.
Целочисленная арифметика спасает мир. Понятно, что существует решение, где прямая разбиение попадает в одну из свечей с отклонение в ε. Как проще всего отклониться от вектора v на эпсилон в целых - находим вектор kv, не лежащий внутри торта, и берём, например, вектор kv + (0, 1). Его координаты будут взаимно просты, значит строго внутри угла между векторами kv и kv + 1 не будет целых точек в торте.
Вот и перебираем для каждой свечи вектора kv + ( ± 1, ± 1) в качестве направляющих в разрезе. Пишется архипросто.
мы искали такой порядок из данных 4 векторов, что численное векторное произведение любых двух подряд идущих больше нуля (почти сортировка по углу). если таких нет, то NO
У меня прошло такое:
Пусть каждый кусок имеет свой номер (от 1 до 4 против часовой стрелки).
Очевидно направление кратчайшего поворота вокруг центра между свечами на последовательных кусках (например от свечи на 1 к свече на 2, порядок важен) должно быть положительным (против часовой стрелки), т.е. синус угла этого поворота положителен, а значит положителен модуль векторного произведения радиус-векторов этих свечей, т.е. X1*Y2-X2*Y1>0 для кусков 1 и 2 ( (X1;Y1) и (X2;Y2) это координаты свечей на кусках 1 и 2). Для остальных аналогично.
Также очевидно, что угол поворота между свечами на не соседних кусках (например 1 и 3) больше 90, т.е. косинус угла этого поворота отрицателен, а значит отрицтельно скалярное произведение радиус-векторов этих свечей, т.е. X1*X3-Y1*Y3<0
Теперь переберем все возможные расстановки свечей по кускам и проверим их на соответствие указанным условиям (утверждается, что их выполнения достаточно для корректности расстановки). Если хотя-бы одна расстановка корректна, ответ 'YES', иначе 'NO'.
PS: не забываем, что указанные выше значения могут не влезть в 32-битное целое
Интересуют решения задач: А, D, E, F, G, H в сложной номинации;
Больше всего интересно Д, кто-нибудь?
Задача Б:
Отсортируем все коробки по количеству конфет в них (пусть это будет массив a)
Далее для каждого запроса будем бинарным поиском искать ту позицию(p), начиная с которой наглость позволяет съесть по одной конфетой (для каждого i: p ≤ i выполнялось ai > = x, где x - запрос).
После того как мы нашли такую позицию, ответ будет n - p + 1. Теперь обновим с помощью дерева отрезков наш отрезок [p, n] отняв от него единицу. Так как уменьшается только на единицу, отсортированность останется.
Ну да, когда вы хотите посмотреть элемент в бинпоиске, просто спускаетесь по дереву и считаете все изменения.
В итоге O(mlog2n)
Можно M log N, если строить дерево для минимумов и в нем искать границу
D элементарна. Создаем массив, в котором будем на i-том месте хранить скорость на i-том километре. Читаем исходный массив, и пока встречаем нули, заполняем массив скоростей последовательными числами. Как только встречаем число, большее нуля, то начинаем идти обратно также записывая последовательные числа начиная с максимальной скорости, пока в какой-то момент последовательность скоростей не станет правильной (т.е такой, как она описана в задаче). Если же максимальная скорость больше возможной, то записываем эту возможную. Так продолжаем до самого конца. Ну, и чтобы найти время, естественно надо просуммировать все числа, обратные скоростям.
Покажу как будет изменяться по такому алгоритму массив скоростей на первом тесте:
0 0 2 0 0 0 1
1 2 2 0 0 0 1
1 2 2 3 4 5 1
1 2 2 3 4 2 1
1 2 2 3 3 2 1- искомый массив скоростей.
Видимо, это товарищ из второго дивизиона.
В нашем можно было заметить, что график скорости от пройденного расстояния выглядит как-то так:
........._.
.._....._._
._...._..**
..**__*_*..
_*..**.*...
*..........
Можно было понять по-другому. Понятно, что если A[i] - массив ограничений, а V[i] - массив скоростей в оптимальном ответе, то очевидно необходимым является ограничение - V[i] <= A[j] + |j - i| для любого j - действительно, необходимо успеть разогнаться от скорости не выше A[j] до скорости V[i] за |j - i| участков. Значит V[i] <= min{A[j] + |j - i|}. А если взять V[i] просто равным такому минимуму, то несложно заметить, что |V[i + 1] - V[i]| <= 1, то есть такая последовательность скоростей удовлетворяет условию.
Массив V[i] насчитывается очевидным образом за два прохода.
Не не не, мы из сложного, и у нас все прошло
Извиняюсь за поклеп)Ага, слабые тесты детектед!Ах блин, не углядел линейное решение.
Это решение работает за квадрат, что может не вписяться по времени (например на тесте 100000 99999 99998 ... 3 2 1)
Решение за линейное время: 0)считаем данные в массив a.
1) посчитаем для каждого участка максимальную скорость, проехав с которой этот участок мы не разобьемся на этом и следующих участках:
b[n+1]:=1000000;
for i:=n downto 1 do
begin
b[i]:=b[i+1]+1;
if b[i]>a[i] then b[i]:=a[i];
end;
2)для каждого участка определим максимальную скорость, до которой мы сможем разогнаться и проехав с которой этот участок мы не разобьемся на этом и следующих участках:
c[0]:=0;
for i:=1 to n do
begin
c[i]:=c[i-1]+1;
if c[i]>b[i] then c[i]:=b[i];
end;
4)Посчитаем, за какое время он с посчитанными выше скоростями пройдет весь путь (сумма обратных скоростям величин)
PS: Как-то объемисто получилось... Никто не подскажет, как сообщения компактнее форматировать? (Уменьшить интервалы хотябы)
1 99999 ... 3 2 1
1 2 ... 3 2 1
...
1 2 ... 50000 49999... 3 2 1 (50000-ная итерация) и еще 50000 ничего не изменяющих итераций. Итого 100000 итераций, что проходит за секунду
Там решение за O(1).
Закономерность легко находится.
Координаты:
(1;1)
____
(2;1)
(1;2)
____
(1;3)
(2;2)
(3;1)
_____
(4;1)
(3;2)
(2;3)
(1;4)
_____
(1;5)
(2;4)
(3;3)
(4;2)
(5;1)
____
(6;1)
....
Постарайтесь найти сами.
В первой диагонали 1 дробь, во второй - две, в третьей - три, и т.д.
Станкевич задачи у меня ворует, что же делать, что же делатьУ нас арифметическая прогрессия, с помощью формулы или бинпоиска находим нужную диагональ, дальше все понятно.
Забавно, сам недавно делал почти такую же задачу (чуть посложнее), условие тут
Простите, http://www.spoj.pl/problems/CANTON/
Разве что там ограничения хлюпенькие..
Нашел диагональ(id> n) с четными показателями i, j, потом двигался по ней единичными шагами на уменьшение id. Когда понял, что на 1018 работает за >10 сек, пришлось оптимизировать до более разумного подхода без единичных шагов, но <1.5 сек сделать не удалось, к счастью для принятия задачи этого хватило.
Расстроила ошибка в примерах, на которой ломал голову, понимая где я что не так понял.
Если выписать дроби подряд в указанном порядке, посмотрим сумму числителя и знаменателя для каждой дроби. Будет ряд 2, 3, 3, 4, 4, 4 и так далее.
Зная порядковый номер нужной дроби, найдем сумму ее числителя и знаменателя. Для этого нужно решить уравнение:
t * (t - 1) / 2 < x <= t * (t + 1) / 2
(можно решить дихотомией, например)
и суммой будет t + 1
потом находим порядковый номер искомой дроби в ряду с полученной суммой числителя и знаменателя как n = x - t * (t - 1)
ну а там уже в зависимости от четности t ряд с данной суммой будет выглядеть как 1/n, 2/(n-1), 3/(n-2) и так далее, либо n/1, (n-1)/2, (n-2)/3
ответ уже вывести несложно, нужно найти n-ое число в ряду с постоянной суммой числителя и знаменателя
как-то так
так же понятно, что в каждой следующей диагонали на 1 больше, чем в предыдущей. тогда первый номер элемента диагонали имеет вид x * (x - 1) / 2 + 1, последний - x * (x + 1) / 2 для некоторого x. находим x дихотимией(или как-нибудь хитро за О(1)).
тогда если x - четно, то ответ (x + 1 - k) / k, иначе k / (x + 1 - k), где k - номер элемента на диагонали, равный n - x * (x - 1) / 2
От себя: дфс можно было и не писать - Краскал спокойно работает и на несвязных графах.
Извините, это про задачу Honeywar?
UPD: перекачал условие, видимо это задача "Прыгать!"
Проходит со свистом.
UPD:
Расскажи задачку про перестановки, интересно.
блин, я криворукий дебил. точнее, нервы к концу контеста сдали, видимо, не додебажил((
ВА5 словил
кода наворотил, конечно)
UPD нашел баг. мы корявые психи, конечно
да)
Я готов повеситься :( Полконтеста пытался найти баги, но остановился на WA15. У меня там жесть случаев разных.
а мы кроме этой 2 халявы так и не сдали((
на эту задачу около получаса убили, уже на 3м тесте упали) потом забили и стали писать несданную халяву
А то у меня все западает на "Решаю ЭТУ задачу, пока не сдам или не будет -10".
Таким образом получается, что многие задачи я даже не читал. Это нормально?