Considere la siguiente pregunta de Google Code Jam ronda 1C :
La Gran Muralla de China comienza como una línea infinita, donde la altura en todos los lugares es .
Algún número de tribus , atacarán el muro de acuerdo con los siguientes parámetros: un día de inicio, , una fuerza de inicio , una coordenada de inicio oeste, y una coordenada de inicio este, . Este primer ataque se produce en el día , en rango , en la fuerza . Si hay alguna porción de la Gran Muralla dentro de que tiene una altura , el ataque es exitoso, y al final del día, la pared se construirá de tal manera que cualquier segmento de ella dentro de de altura estaría entonces en altura (o mayor, si algún otro ataque ese día golpeó el mismo segmento con fuerza )
Cada tribu realizará hasta ataques antes de retirarse, y cada ataque se determinará iterativamente a partir del anterior. Cada tribu tiene algunos , y δ S que determinan su secuencia de ataques: esperarán δ D ≥ 1 días entre ataques, moverán sus unidades de rango de ataque para cada ataque (negativo = oeste, positivo = este), aunque el tamaño del rango seguirá siendo el mismo, y su fuerza también aumentará / disminuirá en un valor constante después de cada ataque.
El objetivo del problema es, dada una descripción completa de las tribus atacantes, determinar cuántos de sus ataques serán exitosos.
Logré codificar una solución que funciona, ejecutándose en unos 20 segundos: creo que la solución que implementé toma tiempo , donde el número total de ataques en una simulación (máx. ) y el número total de puntos de borde únicos en los rangos de ataque (máx. ).
En un nivel alto, mi solución:
- Lee en toda la información de la tribu
- Calcula todas las coordenadas únicas para los rangos de ataque -
- Representa el Muro como un árbol binario perezosamente actualizado sobre larangos X que rastrea los valores mínimos de altura. Una hoja es el lapso de doscoordenadas X sin nada en el medio, y todos los nodos principales representan el intervalo continuo cubierto por sus hijos. - O ( X log X )
- Genera todos los ataques que realizará cada tribu, y los ordena por día -
- Para cada ataque, vea si sería exitoso ( tiempo de consulta). Cuando cambie el día, recorra todos los ataques exitosos no procesados y actualice el muro en consecuencia ( registre el tiempo de actualización X para cada ataque). - O ( Un log X )
Mi pregunta es esta: ¿hay alguna manera de hacerlo mejor que ? Quizás, ¿hay alguna forma estratégica de aprovechar la naturaleza lineal de los sucesivos ataques de Tribes? 20 segundos se sienten demasiado largos para una solución prevista (aunque Java podría ser el culpable de eso).