Рассмотрим следующий вопрос Google Code Jam в 1С :
Великая китайская стена начинается бесконечной линией, где высота во всех местах равна .
Некоторое количество племен , , будет атаковать стену в соответствии со следующими параметрами - начальный день, , начальная сила , начальная западная координата и начальная восточная координата , Это первое нападение происходит на день , на интервале , по прочности . Если в пределах есть какая-либо часть Великой стены , высота которой , атака будет успешной, и в конце дня стена будет построена так, что любой ее сегмент в пределах высоты тогда будет на высоте (или больше, если какая-то другая атака в тот день поразит тот же сегмент с силой S ′ > S )
Каждое племя выполнит до атак перед отступлением, и каждая атака будет определяться итеративно по сравнению с предыдущей . Каждое племя имеет несколько δ D , δ X и δ S, которые определяют их последовательность атак: они будут ожидать δ D ≥ 1 дня между атаками, они будут перемещать свой диапазон атаки δ X единиц для каждой атаки (отрицательный = запад, положительный = восток), хотя размер диапазона останется прежним, и их сила также будет увеличиваться / уменьшаться на постоянное значение после каждой атаки.
Цель этой проблемы, учитывая полное описание атакующих племен, определить, сколько их атак будет успешным.
Мне удалось зашифровать решение, которое работает и работает примерно за 20 секунд: я полагаю, что реализованное мною решение занимает время , где A = общее количество атак в симуляции (макс. 1000000 ), а X = общее количество уникальных краевых точек на диапазонах атаки (макс. 2000000 ).
На высоком уровне мое решение:
- Читает во всей информации племени
- Вычисляет все уникальные координаты для дальности атаки - O ( A )
- Представляет стену в виде лениво обновленного двоичного дерева в диапазонах которое отслеживает минимальные значения высоты. Лист - это промежуток двух X- координат, между которыми ничего нет, и все родительские узлы представляют непрерывный интервал, охватываемый их дочерними элементами . - O ( X log X )
- Формирует все атаки каждое племя будет выполнять, и сортирует их в день -
- Для каждой атаки посмотрите, будет ли она успешной ( время запроса). Когда день изменится, пройдитесь по всем необработанным успешным атакам и обновите стену соответствующим образом ( log X время обновления для каждой атаки). - O ( A log X )
Мой вопрос заключается в следующем: есть ли способ сделать лучше, чем ? Возможно, есть какой-то стратегический способ воспользоваться линейным характером последовательных атак племен? 20 секунд кажется слишком долгим для предполагаемого решения (хотя в этом может быть виновата Java).