Dada una secuencia de enteros y un tamaño de ventana , para cada posición de la secuencia hay que encontrar el máximo de la ventana que termina en . La ventana contiene los elementos desde la posición hasta (ambos incluidos).
Para resolver este problema de manera eficiente, usaremos una cola de prioridad (en nuestro caso, un max-heap) que almacena pares (valor, índice). Definimos el struct:
struct Elem {
int valor;
int index;
};
con la comparación:
bool operator>(const Elem& a, const Elem& b) {
return a.valor > b.valor;
}
La técnica para poder hacer esto es la siguiente. Para cada nuevo
elemento de la secuencia, lo insertamos en la cola de prioridad.
Después, mientras el elemento de la cima tenga un índice fuera de la
ventana (es decir, index <= i - W), lo extraemos. El
máximo actual de la ventana será, entonces, el valor de la cima de la
cola de prioridad.
Esta técnica se llama “borrado perezoso” (lazy deletion): los elementos que ya no pertenecen a la ventana no se eliminan inmediatamente, sino que se extraen solo cuando llegan a la cima del heap. Esto hace que el algoritmo sea muy eficiente en la práctica.
La primera línea contiene un entero (), el tamaño de la ventana. A continuación, una secuencia de enteros separados por espacios hasta el final de la entrada.
Para cada posición de la secuencia (empezando por la primera), el máximo de la ventana correspondiente, uno por línea.
Este es un problema de eficiencia. Una solución ingenua que recorra toda la ventana para cada posición no pasará los casos de prueba grandes, pero la solución con una cola de prioridad sí.
Hay que enviar un fichero program.cc que incluya
"heap.hh". En los ficheros públicos encontrarás
heap.hh y assert.hh.
Input
3 1 3 2 5 4 1 7 2
Output
1 3 3 5 5 5 7 7
Input
1 5 3 8 1
Output
5 3 8 1