Docsity
Docsity

Prepara tus exámenes
Prepara tus exámenes

Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity


Consigue puntos base para descargar
Consigue puntos base para descargar

Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium


Orientación Universidad
Orientación Universidad


Ejercicios de Iteración, Ejercicios de Estructuras de Datos y Algoritmos

Ejercicios iterativos, juez DOMJudge resueltos con coste, especificación e invariante

Tipo: Ejercicios

2020/2021

Subido el 27/03/2021

CarlosGV11
CarlosGV11 🇪🇸

4.6

(25)

5 documentos

1 / 31

Toggle sidebar

Esta página no es visible en la vista previa

¡No te pierdas las partes importantes!

bg1
Temperaturas extremas
La Agencia Estatal de Meteorolog´ıa (AEMET) actualiza diaria-
mente el Banco Nacional de Datos Climatol´ogicos, en el que se alma-
cenan las observaciones climatol´ogicas (precipitaci´on y temperatura)
realizadas en Espa˜na desde hace unos 150 nos.
Nuria est´a estudiando la relaci´on entre la variabilidad de la tem-
peratura y el estado ıdrico del suelo en una regi´on de secano en
Espa˜na. Para ello, acude al Banco y solicita los registros de tempe-
raturas en dicha zona no a no desde que existen registros.
En la primera fase de su estudio pretende determinar el umero de
picos y valles en las temperaturas en un determinado periodo de tiempo. Una temperatura se considera
pico (resp. valle) en una secuencia cuando la anterior y la siguiente en la secuencia son estrictamente
menores (resp. mayores).
Entrada
La primera l´ınea contiene un umero que indica el umero de casos de prueba que aparecen a
continuaci´on.
Cada caso de prueba se compone de dos ıneas. La primera de ellas tiene un ´unico entero con el
umero de temperaturas registradas (mayor que 0 y menor o igual que 10.000), mientras que la segunda
l´ınea contiene la secuencia de temperaturas (n´umeros enteros entre –50 y 60 grados cent´ıgrados).
Salida
Para cada caso de prueba se escribir´a el umero de picos y de valles, separados por un espacio y
seguidos de un salto de l´ınea.
Entrada de ejemplo
4
5
75389
8
89765342
2
3 -5
8
4-1537768
Salida de ejemplo
0 1
2 1
0 0
1 3
Nota
Este ejercicio debe verse en el contexto de la asignatura de Fundamentos de Algoritmis (FAL), FDI-
UCM 2019/2020 (prof. Clara Mar´ıa Segura Diaz). Por tanto no vale cualquier soluci´on, sino olo aquellas
que utilicen los conceptos de FAL. Es muy posible que se den aclaraciones adicionales en clase a este
respecto.
1
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f

Vista previa parcial del texto

¡Descarga Ejercicios de Iteración y más Ejercicios en PDF de Estructuras de Datos y Algoritmos solo en Docsity!

Temperaturas extremas

La Agencia Estatal de Meteorolog´ıa (AEMET) actualiza diaria- mente el Banco Nacional de Datos Climatol´ogicos, en el que se alma- cenan las observaciones climatol´ogicas (precipitaci´on y temperatura) realizadas en Espa˜na desde hace unos 150 a˜nos. Nuria est´a estudiando la relaci´on entre la variabilidad de la tem- peratura y el estado h´ıdrico del suelo en una regi´on de secano en Espa˜na. Para ello, acude al Banco y solicita los registros de tempe- raturas en dicha zona a˜no a a˜no desde que existen registros. En la primera fase de su estudio pretende determinar el n´umero de picos y valles en las temperaturas en un determinado periodo de tiempo. Una temperatura se considera pico (resp. valle) en una secuencia cuando la anterior y la siguiente en la secuencia son estrictamente menores (resp. mayores).

Entrada

La primera l´ınea contiene un n´umero que indica el n´umero de casos de prueba que aparecen a continuaci´on. Cada caso de prueba se compone de dos l´ıneas. La primera de ellas tiene un ´unico entero con el n´umero de temperaturas registradas (mayor que 0 y menor o igual que 10.000), mientras que la segunda l´ınea contiene la secuencia de temperaturas (n´umeros enteros entre –50 y 60 grados cent´ıgrados).

Salida

Para cada caso de prueba se escribir´a el n´umero de picos y de valles, separados por un espacio y seguidos de un salto de l´ınea.

Entrada de ejemplo

Salida de ejemplo

Nota

Este ejercicio debe verse en el contexto de la asignatura de Fundamentos de Algoritmis (FAL), FDI- UCM 2019/2020 (prof. Clara Mar´ıa Segura Diaz). Por tanto no vale cualquier soluci´on, sino s´olo aquellas que utilicen los conceptos de FAL. Es muy posible que se den aclaraciones adicionales en clase a este respecto.

...MJudge\Problemas\1 - Iterativos\1 - Iterativos\AC01.cpp 1

1 2 3 4 5 6 7 8 9

#include #include #include using namespace std;

struct tTemperaturas { int numPicos; int numValles; };

/* ESPECIFICACIÓN DE LA FUNCIÓN ITERATIVA.

  • Precondición: requires 0 < v.size() <= 10.000 && forall p : 0 <= p < v.size () : v[p] >= - 50 && v[p] <= 60.
  • Postcondición: ensures sol.numPicos = #a : 1 <= a < v.size() - 1 : v[a] > v[a
  • 1] && v[a] > v[a + 1].
  • ensures sol.numValles = #b : 1 = b < v.size() - 1 : v[b] < v[b
  • 1] && v[b] < v[b + 1]. */

tTemperaturas iterativa(const vector & v) { tTemperaturas sol = {0, 0}; for (int pos = 1; pos < v.size() - 1; pos++) { /* DISEÑO DEL ALGORITMO ITERATIVO.

  • Función de cota: decreases v.size() - pos.
  • Invariante: invariant 1 <= pos <= v.size() - 1.
  • invariant sol.numPicos = #a : 1 <= a < pos : v[a] > v[a - 1] && v[a] > v[a + 1].
  • invariant sol.numValles = #b : 1 <= b < pos : v[b] < v[b
  • 1] && v[b] < v[b + 1]. */ if (v[pos] > v[pos - 1 ] && v[pos] > v[pos + 1]) sol.numPicos++; else if (v[pos] < v[pos - 1 ] && v[pos] < v[pos + 1]) sol.numValles++; } return sol; }

/* COSTE DE LA FUNCIÓN ITERATIVA.

  • La función iterativa, cuyas instrucciones tienen todas coste constante, contiene un bucle for que itera v.size() - 2 veces
  • sobre el vector de entrada. Por lo tanto, como en términos asintóticos O (v.size() - 2) = O(v.size()), el coste de la función
  • iterativa es lineal con respecto al número de elementos que hay en el vector.

*/

void resolverCasoDePrueba() { int n; cin >> n; vector v(n); for (int pos = 0; pos < n; pos++) cin >> v[pos];

tTemperaturas sol = iterativa(v); cout << sol.numPicos << " " << sol.numValles << endl; }

int main() { #ifndef DOMJUDGE std::ifstream in("AC01.in");

Problema 3

Implementar un algoritmo que resuelva el siguiente problema: method problema3 ( a : array < int > , p : int ) returns ( b : bool ) requires a != null requires 0 <= p < a. Length ensures b == forall u , w :: 0 <= u <= p < w < a. Length == > a [ u ] < a [ w ]

Requisitos de implementaci´on.

  • El orden de complejidad del algoritmo debe ser lineal respecto al n´umero de elementos del vector.
  • Debe utilizarse la clase vector para almacenar los datos y llamar a la funci´on resolver

Entrada

La entrada comienza con un valor entero que indica el n´umero de casos de prueba. Cada caso de prueba consta de dos l´ıneas. La primera contiene el n´umero de elementos del vector y el valor de p. La segunda l´ınea contiene los valores del vector.

Salida

Para cada caso de prueba se escribe en una l´ınea SI si el resultado de la funci´on es cierto y NO si es falso.

Entrada de ejemplo

Salida de ejemplo

SI

SI

SI

NO

Autor: Isabel Pita.

...MJudge\Problemas\1 - Iterativos\1 - Iterativos\AC02.cpp 1

1 2 3 4 5 6 7 8 9

#include #include #include using namespace std;

/* ESPECIFICACIÓN DE LA FUNCIÓN ITERATIVA.

  • Precondición: requires 0 <= p < v.size().
  • Postcondición: ensures b == forall u, w : 0 <= u <= p < w < v.size() : v[u] < v[w]. */

bool iterativa(const vector& v, int p) { bool b = true; if (p + 1 != v.size()) { int min_derecha = v[p + 1]; for (int pos_derecha = p + 2; pos_derecha < v.size(); pos_derecha++) { /* DISEÑO DEL ALGORITMO ITERATIVO (BUCLE FOR).

  • Función de cota: decreases v.size() - pos_derecha.
  • Invariante: invariant p + 2 <= pos_derecha <= v.size().
  • invariant min_derecha = min w : p + 2 <= w < pos_derecha : v[w]. */ if (min_derecha > v[pos_derecha]) min_derecha = v[pos_derecha]; }

int pos_izquierda = 0; while (pos_izquierda <= p && b) { /* DISEÑO DEL ALGORITMO ITERATIVO (BUCLE WHILE).

  • Función de cota: decreases p + 1 - pos_izquierda.
  • Invariante: invariant 0 <= pos_izquierda <= p + 1. invariant b == forall w : 0 <= u < pos_izquierda : v [u] >= min_derecha. */ if (v[pos_izquierda] >= min_derecha) b = false; pos_izquierda++; } } return b; }

/* COSTE DE LA FUNCIÓN ITERATIVA.

  • La función iterativa, cuyas instrucciones tienen todas conste constante, contiene un bucle for y un bucle while. El bucle
  • for en el caso peor itera v.size() - (p + 2) veces y el bucle while, en el caso peor, itera p + 1 veces. Por lo tanto, en
  • conjunto, la función iterativa en el caso peor itera v.size() - (p + 2) + (p
    1. veces, y como en términos asintóticos
  • O(v.size() - 1) = O(v.size()), el coste de la función es lineal con respecto al número de elementos del vector. */

void resolverCasoDePrueba() { int n, p; cin >> n >> p; vector v(n); for (int pos = 0; pos < n; pos++) cin >> v[pos];

if (iterativa(v, p)) cout << "SI" << endl;

Rescate aereo 1

Despu´es de sufrir un devastador ataque alien´ıgena, el alto mando ha recibido una llamada de rescate de la ciudad de Nueva York. El grupo de supervivientes se encuentra detras de la l´ınea de rascacielos de la ciudad. Al otro lado de los edificios se encuentra vigilando una nave extraterrestre. Para evitar que el transporte aereo encargado del rescate sea detectado por la nave enemiga, hemos encontrado la secuencia m´as larga de edificios cuya altura es estrictamente mayor que la de nuestro transporte. El alto mando ya ha avisado a los supervivientes para que se dirigan a este punto de encuentro. Suponemos que todos los edificios tienen la misma anchura.

Requisitos de implementaci´on. Indicar el coste de la soluci´on obtenida. La funci´on que resuelve el problema debe recibir los datos en un vector y devolver el comienzo y final del intervalo.

Entrada

La entrada comienza con el n´umero de casos de prueba. Cada caso de prueba tiene dos l´ıneas. En la primera se indica el n´umero de edificios de la l´ınea n, seguido de la altura del transporte t. En la segunda se indica la altura de cada edificio de la l´ınea. Se supone que la altura del transporte es menor que la altura de alguno de los edificios considerados y por lo menos existe un edificio.

Salida

Para cada caso de prueba se escriben en una l´ınea el comienzo y el final del intervalo. En caso de existir dos intervalos iguales se eligir´a el de la izquierda.

Entrada de ejemplo

Salida de ejemplo

Autor: Isabel Pita.

...MJudge\Problemas\1 - Iterativos\1 - Iterativos\AC03.cpp 1

1 2 3 4 5 6 7 8 9

#include #include #include using namespace std;

struct tExtremos { int inferior; int superior; };

/* ESPECIFICACIÓN DE LA FUNCIÓN ITERATIVA.

  • Precondición: requires (#i : 0 <= i < v.size() : v[i] > t) > 0
  • Postcondición: ensures sol.superior - sol.inferior = (max p, q : 0 <= p <= q <= v.size() && forall r : p <= r < q : v[r] > t) : q - p */

tExtremos iterativa(const vector& v, int t) { tExtremos sol = {0, 0}; int a = 0, l = - 1; for (int b = 0; b < v.size(); b++) { /* DISEÑO DEL ALGORITMO ITERATIVO.

  • Función de cota: decreases v.size() - b.
  • Invariante: invariant 0 <= b <= v.size().
  • invariant l == (max c : a <= c <= b && forall d : c <= d < b : v[d] > t) : b - c.
  • invariant sol.superior - sol.inferior = (max p, q : 0 <= p <= q <= b && forall r : p <= r < q : v[r] > t) : q - p. */ if (v[b] > t) { a = b; while (b < v.size() && v[b] > t) { if (b - a > l) { l = b - a; sol = {a, b}; } b++; } } } return sol; }

/* COSTE DE LA FUNCIÓN ITERATIVA.

  • La función iterativa, cuyas instrucciones tienen todas coste constante, contiene un bucle for externo y un bucle while
  • interno, que en conjunto y en cualquier caso, itera v.size() veces sobre el vector. Por lo tanto, el coste de la función
  • es O(v.size()), es decir, lineal con respecto al número de elementos del vector. */

void resolverCasoDePrueba() { int n, t; cin >> n >> t; vector v(n); for (int pos = 0; pos < n; pos++) cin >> v[pos];

tExtremos sol = iterativa(v, t); cout << sol.inferior << " " << sol.superior << endl; }

Encuentra la ´ultima posici´on de equilibrio

Implementa una funci´on que resuelva el siguiente problema: function numUnos ( s : seq < int >) : int ensures s == [] == > numUnos ( s ) == 0 ensures s != [] && s [0] == 1 == > numUnos ( s ) == 1 + numUnos ( s [1..]) ensures s != [] && s [0] != 1 == > numUnos ( s ) == numUnos ( s [1..])

function numCeros ( s : seq < int >) : int ensures s == [] == > numCeros ( s ) == 0 ensures s != [] && s [0] == 0 == > numCeros ( s ) == 1 + numCeros ( s [1..]) ensures s != [] && s [0] != 0 == > numCeros ( s ) == numCeros ( s [1..])

method xxx ( v : array < int >) returns ( p : int ) requires v != null ensures -1 <= p < v. Length ensures numUnos ( v [.. p +1]) == numCeros ( v [.. p +1]) ensures forall k :: p < k < v. Length == > numUnos ( v [.. k +1]) != numCeros ( v [.. k +1])

Requisitos de implementaci´on. Indicar el coste de la soluci´on obtenida. La funci´on que resuelve el problema debe recibir los datos en un vector y devolver el valor de la posici´on (observad que puede ser -1).

Entrada

La entrada comienza con el n´umero de casos de prueba. Cada caso de prueba tiene dos l´ıneas. En la primera l´ınea se indica el tama˜no del vector, en la segunda los valores separados por blancos.

Salida

Para cada caso de prueba se escribe en una l´ınea el valor de la posici´on pedida. Si el tama˜no del vector es cero la posici´on debe ser -1.

Entrada de ejemplo

Salida de ejemplo

...MJudge\Problemas\1 - Iterativos\1 - Iterativos\AC04.cpp 1

1 2 3 4 5 6 7 8 9

#include #include #include using namespace std;

struct tInfo { int unos; int ceros; };

/* ESPECIFICACIÓN DE LA FUNCIÓN ITERATIVA.

  • Precondición: requires v.size() >= 0
  • Postcondición: ensures - 1 <= p < v.size() && exists u : 0 <= u < v.size() : num.unos == num.ceros && forall w : u < w < v.size() : num.unos != num.ceros */

int iterativa(const vector& v) { int p = - 1; tInfo num = {0, 0}; for (int pos = 0; pos < v.size(); pos++) { /* DISEÑO DEL ALGORITMO ITERATIVO.

  • Función de cota: decreases v.size() - pos.
  • Invariante: invariant 0 <= pos <= v.size().
  • invariant num.ceros = #a : 0 <= a < pos : v[a] == 0
  • invariant num.unos = #b : 0 <= b < pos : v[b] == 1
  • invariant - 1 <= p < pos && exists u : 0 <= u < pos : num.ceros == num.unos && forall w : pos < w < v.size() : num.unos != num.ceros */ if (v[pos] == 0) num.ceros++; else if (v[pos] == 1) num.unos++;

if (num.ceros == num.unos) p = pos; } return p; }

/* COSTE DE LA FUNCIÓN ITERATIVA.

  • La función iterativa, cuyas instrucciones son todas de coste constante, tiene un bucle for que itera v.size() veces sobre
  • el vector. Por lo tanto, el coste de la función iterativa es O(v.size()), es decir, lineal con respecto al número de
  • elementos que contiene el vector. */

void resolverCasoDePrueba() { int n; cin >> n; vector v(n); for (int pos = 0; pos < n; pos++) cin >> v[pos];

cout << iterativa(v) << endl; }

int main() { #ifndef DOMJUDGE std::ifstream in("AC04.in"); auto cinbuf = std::cin.rdbuf(in.rdbuf()); #endif

Creciente por los pelos y divertido

Teniendo en cuenta las dos definiciones siguientes:

  • Se dice que un vector es creciente por los pelos cuando, adem´as de ser creciente, la diferencia entre un elemento y el elemento siguiente es como mucho uno. Por ejemplo, los siguientes vectores de tama˜no 4 cumplen la definici´on:

F´ıjate que al no exigirse que el vector sea estrictamente creciente, el ´ultimo vector con todos 1 ’s cumple la definici´on. Por su parte el vector

no es creciente por los pelos, pues no es creciente.

  • Los vectores aburridos son aquellos en los que hay elementos que apare- cen repetidos muchas veces. Se dice que un vector es d-divertido cuando ning´un elemento se repite m´as de d veces. Ejemplos de vectores 1-divertido son

pues ning´un elemento aparece m´as de una vez (f´ıjate que, en realidad, los vectores anteriores son tambi´en 10-divertidos, pues ning´un elemento aparece m´as de 10 veces).

Especifica, dise˜na e implementa una funci´on que reciba un vector de enteros de longitud 0 ≤ n ≤ 1000 y un par´ametro d > 0 y devuelva si el vector es creciente por los pelos y d-divertido. Escribe el invariante y funci´on de cota que permitan demostrar la correcci´on del algoritmo implementado. Por ´ultimo, justifica el coste del algoritmo conseguido.

Entrada

La primera l´ınea contiene un n´umero que indica el n´umero de casos de prueba que aparecen a continuaci´on. Cada caso de prueba registra en el primer n´umero el n´umero m´aximo de veces que se puede repetir un elemento en el vector, en el segundo, el n´umero de elementos del vector, y a continuaci´on los elementos del vector separados por blancos.

Salida

Para cada caso de prueba se escribir´a en una l´ınea el vector modificado y en otra l´ınea la posici´on de separaci´on.

Entrada de ejemplo

Salida de ejemplo

SI

NO

NO

NO

SI

SI

SI

NO

NO

NO

SI

NO

...MJudge\Problemas\1 - Iterativos\1 - Iterativos\AC05.cpp 2

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

vector v(n); for (int pos = 0; pos < n; pos++) cin >> v[pos];

if (iterativa(v, d)) cout << "SI" << endl; else cout << "NO" << endl; }

int main() { #ifndef DOMJUDGE std::ifstream in("AC05.in"); auto cinbuf = std::cin.rdbuf(in.rdbuf()); #endif

int numCasos; cin >> numCasos; for (int i = 0; i < numCasos; ++i) { resolverCasoDePrueba(); }

#ifndef DOMJUDGE std::cin.rdbuf(cinbuf); system("PAUSE"); #endif

return 0; }

Ejercicio 1

Dado un vector de n´umeros enteros positivos, V [0..N ], N ≥ 0 ordenado en orden estrictamente creciente, se pide dise˜nar un algoritmo eficiente O(N ) que elimine todos los n´umeros impares, dejando s´olo los pares, ordenados de forma creciente. El procedimiento modificar´a el vector de entrada y su tama˜no, y no deber´a utilizar ning´un array auxiliar. Los par´ametros por lo tanto ser´an de entrada/salida. Se pide:

  • Especificar el problema.
  • Dise˜nar e implementar un algoritmo que resuelva el problema.
  • Escribir un invariante y una funci´on cota que permitan demostrar la correcci´on del algoritmo implementado.
  • Justificar el coste del algoritmo.

Entrada

La entrada que espera el corrector autom´atico consta de una serie de casos de prueba y acabar´a cuando se introduzca un -1. Cada caso de prueba consta de dos l´ıneas, en la primera se indica el n´umero de elementos del vector. En la segunda se dan los elementos, ordenados en orden estrictamente creciente y separados por el car´acter blanco. Se cumple que el n´umero de elementos del vector es mayor o igual que cero y cada componente del vector es estrictamente mayor que cero.

Salida

Para cada caso de prueba se escribe una l´ınea con los elementos que quedan en el vector despu´es de eliminar los elementos impares dejando un espacio blanco entre cada par de elementos. Si en el vector no queda ning´un elemento se deja una l´ınea en blanco.

Entrada de ejemplo

Salida de ejemplo

...MJudge\Problemas\1 - Iterativos\1 - Iterativos\AC06.cpp 2

51 52 53 54 55 56 57 58 59 60 61

#endif

while (resolverCasoDePrueba());

#ifndef DOMJUDGE std::cin.rdbuf(cinbuf); system("PAUSE"); #endif

return 0; }

Heidi, una nueva caba˜na

La caba˜na del abuelo de Heidi est´a situada en los alpes suizos, sobre la aldea de Maienfeld. La caba˜na est´a construida en un peque˜no llano en la ladera de la monta˜na, rodeada en su parte trasera por tres enormes abetos, y con una preciosa vista sobre el valle desde su parte delantera. Heidi est´a buscando un lugar donde construir otra caba˜na en el camino hasta las cumbres. Para ello necesita localizar terrenos que tengan una superficie llana suficiente para construir, una vista tan buena como la de la caba˜na de su abuelo y que est´en cerca del camino. Hoy ha ido con Pedro a recolectar los datos. Entre todos los valores que han recogido, ahora deben buscar aquella secuencia que tenga al menos l > 1 valores consecutivos iguales, y que sean mayores o iguales que todos los valores de su derecha, para que tenga buenas vistas.

Requisitos de implementaci´on. Implementar una funci´on que reciba en un vector los datos, y devuelva en un vector diferente del de entrada los puntos donde empiezan los espacios apropiados para construir mirados desde la derecha del vector. La implementaci´on de la funci´on debe tratar cada dato una ´unica vez. La funci´on debe devolver tambi´en la longitud de la secuencia mas larga de valores iguales y que cumpla las condiciones para construir la casa que se haya encontrado.

Entrada

La entrada consta de una serie de casos de prueba. Cada caso de prueba tiene dos l´ıneas. En la primera se indica el n´umero de datos tomados por Heidi y Pedro seguido de la cantidad de valores iguales que necesitan para poder construir (l > 1). En la segunda se indican los valores que han tomado.

Salida

Para cada caso de prueba se escribe en una l´ınea la longitud de la secuencia m´as larga, seguido del n´umero de llanos encontrados, seguido del comienzo de cada llano mirado desde la parte derecha del vector. Tal como est´a dados los datos, los llanos que aparecen en el listado de salida est´an dados desde la derecha del vector, primero las posiciones m´as altas (valores mas bajos).

Entrada de ejemplo

Salida de ejemplo

Autor: Isabel Pita.