Betrachten Sie die folgende Frage zu Google Code Jam in Runde 1C :
Die Chinesische Mauer beginnt als unendliche Linie, wobei die Höhe an allen Stellen .
Einige Anzahl von Stämmen , N ≤ 1000 , wird die Wand der Wand angreifen gemäß den folgenden Parametern - Anfangstag, D , eine Start Stärke S , einen Start west-Koordinate, W , und ein Start-Ost-Koordinate, E . Dieser erste Angriff erfolgt am Tag D , auf Bereich [ W , E ] , an Stärke S . Befindet sich ein Teil der Chinesischen Mauer in [ W , E ] , dessen Höhe < S ist ?Wenn der Angriff erfolgreich ist, wird die Mauer am Ende des Tages so aufgebaut, dass sich jedes Segment innerhalb von der Höhe < S auf der Höhe S befindet (oder größer, wenn ein anderer Angriff erfolgt) dieser Tag traf auf dasselbe Segment mit der Stärke S ′ > S )
Jeder Stamm wird bis zu Angriffe ausführen, bevor er sich zurückzieht, und jeder Angriff wird iterativ von dem vor ihm bestimmten bestimmt. Jeder Stamm hat einige δ D , δ X und δ S , die die Reihenfolge ihrer Angriffe bestimmen: Die warten δ D ≥ 1 Tage zwischen den Angriffen, sie bewegen ihre Angriffsreichweite δ X Einheiten für jeden Angriff (negativ = Westen, positiv = east), obwohl die Größe der Reichweite gleich bleibt und ihre Stärke nach jedem Angriff um einen konstanten Wert zunimmt / abnimmt.
Ziel des Problems ist es, anhand einer vollständigen Beschreibung der angreifenden Stämme zu bestimmen, wie viele ihrer Angriffe erfolgreich sein werden.
Ich habe es geschafft, eine funktionierende Lösung zu codieren, die in etwa 20 Sekunden ausgeführt wurde: Ich glaube, die von mir implementierte Lösung benötigt Zeit, wobei A = die Gesamtzahl der Angriffe in einer Simulation ist (max 1000000 ) und X = die Gesamtzahl der eindeutigen Kantenpunkte in Angriffsbereichen (max 2000000 ).
Auf hohem Niveau meine Lösung:
- Liest alle Stammesinformationen ein
- Berechnet alle eindeutigen Koordinaten für Angriffsbereiche - O ( A )
- Stellt die Wand als verzögert aktualisierten Binärbaum über den Bereichen dar, der die Mindesthöhenwerte verfolgt. Ein Blatt ist die Spanne von zwei X- Koordinaten, zwischen denen sich nichts befindet, und alle übergeordneten Knoten stellen das fortlaufende Intervall dar, das von ihren untergeordneten Knoten abgedeckt wird. - O ( X log X )
- Erzeugt alle Angriffe, die jeder Stamm ausführen wird, und sortiert sie nach Tag -
- Überprüfen Sie für jeden Angriff, ob er erfolgreich sein würde ( query time). Wenn sich der Tag ändert, durchlaufen Sie alle nicht verarbeiteten erfolgreichen Angriffe und aktualisieren Sie die Wand entsprechend ( Aktualisierungszeit von Protokoll X für jeden Angriff). - O ( A log X )
Meine Frage lautet: Gibt es eine Möglichkeit, es besser zu machen als ? Gibt es vielleicht eine strategische Möglichkeit, die Linearität der aufeinanderfolgenden Angriffe der Stämme auszunutzen? 20 Sekunden sind zu lang für eine beabsichtigte Lösung (obwohl möglicherweise Java daran schuld ist).