Considera la seguente domanda di Google Code Jam round 1C :
La Grande Muraglia cinese inizia come una linea infinita, dove l'altezza in tutte le posizioni è .
Alcuni numero di tribù , N ≤ 1000 , attaccherà la parete del muro in base ai seguenti parametri - un giorno di inizio, D , un punto di forza di partenza S , una start-occidentale di coordinate, W , e un inizio est coordinata, E . Questo primo attacco avviene il giorno D , sulla gamma [ W , E ] , in forza S . Se c'è una parte della Grande Muraglia all'interno di [ W , l'attacco ha successo, e alla fine della giornata, il muro sarà costruito in modo tale che qualsiasi segmento di esso all'interno di [ W , E che ha altezza < S di altezza < S sarebbe quindi all'altezza S (o maggiore, se qualche altro attacco quel giorno colpì sullo stesso segmento con forza S ′ > S )
Ogni tribù eseguirà fino a attacchi prima di ritirarsi e ogni attacco sarà determinato iterativamente da quello precedente. Ogni tribù ha alcuni δ D , δ X e δ S che determinano la loro sequenza di attacchi: aspetteranno δ D ≥ giorni tra gli attacchi, sposteranno il loro raggio di attacco δ unità X per ogni attacco (negativo = ovest, positivo = est), sebbene le dimensioni dell'intervallo rimangano invariate e anche la loro forza aumenterà / diminuirà di un valore costante dopo ogni attacco.
L'obiettivo del problema è, data una descrizione completa delle tribù attaccanti, determinare quanti dei loro attacchi avranno successo.
Sono riuscito a codificare una soluzione che funziona, in esecuzione in circa 20 secondi: credo che la soluzione che ho implementato impieghi il tempo , dove A = il numero totale di attacchi in una simulazione (max 1000000 ) e X = il numero totale di punti limite univoci nelle gamme di attacco (max 2000000 ).
Ad alto livello, la mia soluzione:
- Legge tutte le informazioni sulla tribù
- Calcola tutte le coordinate uniche per i range di attacco - O ( A )
- Rappresenta il muro come un albero binario aggiornato pigramente sugli intervalli che tiene traccia dei valori di altezza minima. Una foglia è l'arco di due coordinate X con nulla in mezzo e tutti i nodi padre rappresentano l'intervallo continuo coperto dai loro figli. - O ( registro X
- Genera tutti gli attacchi che ogni tribù eseguirà e li ordina per giorno -
- Per ogni attacco, verifica se ha esito positivo ( tempo di query ). Quando il giorno cambia, esegui il ciclo tra tutti gli attacchi riusciti non elaborati e aggiorna il muro di conseguenza ( registra il tempo di aggiornamento X per ogni attacco). - O ( un registro
La mia domanda è questa: esiste un modo per fare meglio di ? Forse esiste un modo strategico per trarre vantaggio dalla natura lineare degli attacchi successivi delle Tribù? 20 secondi sembra troppo lungo per una soluzione prevista (anche se Java potrebbe essere la colpa per quello).