Cuatro problemas temáticos

Ordenados por dificultad creciente (subjetivamente):

La temática común que relaciona los problemas (al menos, en algunas soluciones) será revelada más adelante :wink:

2 Me gusta

Ahora que ha pasado cierto tiempo, puedo revelar la temática común, en forma de artículo en la Wiki!!

http://wiki.oia.unsam.edu.ar/algoritmos-oia/sliding-window-rmq

4 Me gusta

Fila (solución 1)

La idea principal en la que va a rondar esta solución es invertir la pregunta. En vez de encontrar para cada persona quién lo enoja (si es que alguien lo enoja), lo que vamos a hacer es para cada persona ver a quiénes enoja.

Cada persona enoja a todos los que sean más viejos que él y estén a su derecha. Esto es clave, ¿por qué?, porque aparece la idea de que una persona sea dominada por otra en el siguiente sentido: Si una persona tiene a otra persona más joven a su izquierda, entonces la primera persona no enoja a nadie (o si enoja alguien, podemos afirmar que existe otra que lo enoja a ese alguien con nivel de enojo más alto, que es lo que nos interesa).

¿Cómo podemos usar esta idea para resolver el problema (eficientemente)?

Vamos a tener dos copias de la fila, una con las personas ordenadas por fecha de nacimiento en orden decreciente (por ende la primera persona es la más joven y la última la más vieja), y la otra tal cual como viene, con las fechas de nacimiento pero ordenada por el número que llevan en la fila (el de más a la izquierda es el próximo en ser atendido).

Importante, en la primera (la fila que está ordenada por fecha de nacimiento) nos vamos a guardar qué posición ocupaba en la fila originalmente.

Ahora vamos a tener dos punteros/índices, uno lo llamo i que comienza en i=0, que va a iterar sobre la segunda fila (la que está ordenada por proximidad a la caja). El otro lo llamo j, que comienza al final de la fila que está ordenada por fecha de nacimiento en j=n−1 si es que hay n personas en la fila.

Ahora, la persona que está en i=0 en la fila, ¿a quiénes enoja?.. Como vimos, enoja a todas las personas más viejas que están a su derecha, como es la primera, en particular enojará a todas las que son más viejas que él.

Entonces la forma de simular esto es achicar j mientras la persona en j sea más vieja que la que está en i, y notar que todas ellas estarán enojadas, para saber su nivel de enojo es que necesitamos guardarnos qué posición ocupa el j-ésimo en la fila ordenada por edad.

Una vez que hicimos eso la persona en la posición i no va a enojar a nadie más, entonces avanzamos i. Notemos que si este nuevo i es más viejo que cualquiera anterior, entonces no va a enojar a nadie (acá es donde está dando vuelta la idea de los dominados que vimos).


Si alguien lo resolvió de otra manera, invito a que la cuente (sé que hay al menos una forma distinta a esta de resolver el problema), y quizá esté bueno para practicar “Two Pointer” implementar esta otra forma.

1 me gusta