Розглянемо наступне питання Google Code Jam: раунд 1С :
Велика Китайська стіна починається як нескінченна лінія, де висота в усіх місцях дорівнює .
Деяка кількість колін , N ≤ 1000 , буде атакувати стіну стіни в відповідності з наступними параметрами - початковий день, D , міцність на старт S , старт захід-координату, W і початок сходу-координату, E . Це перший напад відбувається на день D , на інтервалі [ W , Е ] , по міцності S . Якщо в межах [ W , E ] є якась частина Великої стіни , яка має висоту < S, атака успішна, і наприкінці дня стіна буде побудована таким чином, що будь-який її сегмент у межах висоти < S тоді був би на висоті S (або більше, якби якась інша атака того дня вдарив по тому ж сегменту силою S ′ > S )
Кожне плем'я здійснить до атак перед відступом, і кожна атака визначатиметься повторно від тієї, що передує. Кожне плем'я має деякі δ D , δ X та δ S, що визначає їх послідовність атак: зачекати δ D ≥ 1 дні між атаками, вони перемістять діапазон їх атаки δ X одиниць для кожної атаки (негативний = захід, позитивний = схід), хоча розмір дальності залишиться колишнім, і їх сила також буде збільшуватися / зменшуватися на постійне значення після кожної атаки.
Мета проблеми полягає в тому, щоб, давши повний опис наступаючих племен, визначити, скільки їхніх нападів буде успішним.
Мені вдалося кодувати рішення, яке працює, і працює приблизно за 20 секунд: я вважаю, що застосований нами рішення займає час , де A = загальна кількість атак у симуляції (макс. 1000000 ), а X = загальна кількість унікальних крайових точок в діапазонах атаки (макс. 2000000 ).
На високому рівні моє рішення:
- Читає всю інформацію про плем'я
- Обчислює всі унікальні координати для діапазонів атаки - O ( A )
- Представляє Стіну як ліниво оновлене бінарне дерево у діапазонах що відстежує мінімальні значення висоти. Лист - це проміжок двох координат X, між якими нічого немає, і всі батьківські вузли являють собою безперервний інтервал, охоплений їхніми дітьми. - O ( X log X )
- Створює всі атаки, які виконує кожне плем'я, і сортує їх по днях -
- Для кожної атаки дивіться, чи буде вона успішною ( час запиту). Коли день змінюється, перегляньте всі неперероблені успішні атаки та оновіть стіну відповідно ( журнал часу X для кожної атаки). - Про ( журнал Х )
Моє запитання таке: чи є спосіб зробити краще, ніж ? Можливо, є якийсь стратегічний спосіб скористатися лінійним характером послідовних атак племен? 20 секунд відчуває себе занадто довго для передбачуваного рішення (хоча в цьому може бути винен і Java).