Dpto. O.E.I. – U.P.M. ALGORÍTMICA 07/JUL/11 1º) (3,5 Puntos) La pequeña Daniela dispone de X euros para realizar su compra semanal de chucherías. La tienda donde va a realizar sus adquisiciones dispone de 8 tipos de caramelos, cada uno de los cuales, tiene un precio distinto. Daniela quiere saber cuáles son las combinaciones válidas de caramelos que puede adquirir, teniendo en cuenta que una combinación es válida si: 1) La suma del precio de los caramelos que forman la combinación es inferior o igual a X. 2) Si se añade un nuevo caramelo a dicha combinación, la suma del precio de los caramelos que forman la combinación resultante es superior a X. Suponiendo que los precios de los caramelos están almacenados en un vector de 8 posiciones SE PIDE: Desarrollar un algoritmo en Pascal que liste todas las combinaciones válidas de caramelos que se pueden realizar con X euros. PROGRAM CombinacionesDaniela (input, output); CONST N = 8; TYPE TCaramelos = ARRAY[1 .. N] OF Integer; TCombinacion = ARRAY[1 .. N] OF Integer; VAR Caramelos: TCaramelos; Combinacion: TCombinacion; Min, X: Integer; PROCEDURE inicializarCaramelos(VAR Caramelos: TCaramelos); VAR I: Integer; BEGIN FOR I := 1 TO N DO Caramelos[I] := random(100) MOD 9 + 2 END; PROCEDURE escribirCombinacion(Combinacion: TCombinacion); VAR i : Integer; BEGIN FOR i := 1 TO N DO Write(Combinacion[i]: 2); WriteLn END; PROCEDURE inicializarCombinacion(VAR Combinacion: TCombinacion); VAR I : Integer; BEGIN FOR I := 1 TO N DO Combinacion[I] := 0; END; FUNCTION minimo(Caramelos: TCaramelos): Integer; VAR I, Min: Integer; BEGIN Min := MaxInt; FOR I := 1 TO N DO IF Caramelos[I] < Min THEN Min := Caramelos[I]; minimo := Min; END; Universidad Politécnica de Madrid – E.U. Informática Página 1 PROCEDURE Ensayar(Caramelos: TCaramelos; VAR Combinacion: TCombinacion; Min, X, Voy: Integer); VAR Caramelo: Integer; BEGIN FOR Caramelo := Voy TO N DO BEGIN IF Caramelos[Caramelo] <= X THEN BEGIN Combinacion[Caramelo] := Combinacion[Caramelo] + 1; IF Caramelos[Caramelo] + Min > X THEN escribirCombinacion(Combinacion) ELSE Ensayar(Caramelos, Combinacion, Min, X - Caramelos[Caramelo], Caramelo); Combinacion[Caramelo] := Combinacion[Caramelo] - 1; END; END END; BEGIN inicializarCaramelos(Caramelos); inicializarCombinacion(Combinacion); Min := minimo(Caramelos); X := …; Ensayar(Caramelos, Combinacion, Min, X, 1); END. Universidad Politécnica de Madrid – E.U. Informática Página 2 2º) (3,5 Puntos) El alcalde de una ciudad, conocido popularmente como el “vampiro”, quiere realizar la típica operación asfalto de todos los veranos. Tras las quejas de los “indignados” y para perjudicar, lo menos posible, a la circulación de vehículos ha decidido contratar a un ingeniero en informática de la UPM. El alcalde ha proporcionado al ingeniero el plano de la ciudad por medio de un grafo dirigido representado con matriz de costes de tal manera, que los nodos del grafo representan intersecciones de calles (numeradas de 1 a N) y los arcos son los tramos entre dos intersecciones. El alcalde desea asfaltar los tramos problemáticos durante la noche para evitar molestias. Un tramo es problemático si cuando no se encuentra en uso por estar siendo asfaltado impide que un vehículo pueda llegar desde la intersección 1 a la intersección N. SE PIDE: Generar un listado de los tramos problemáticos de la ciudad. Program Prob_TramosProblematicos (input, ouput); CONST N = 4; Infinito = MaxInt; TYPE TVertice = 1 .. N; TGrafo = ARRAY[TVertice, TVertice] OF Integer; TVisitados = ARRAY[TVertice] OF Boolean; VAR G: TGrafo; FUNCTION Camino(G: TGrafo; Origen, Destino: TVertice; VAR Visitados: TVisitados): Boolean; VAR I: TVertice; Aux: Boolean; BEGIN IF Origen = Destino THEN Aux := True ELSE BEGIN Visitados[Origen] := True; Aux := False; I := 1; WHILE (I <= N) AND NOT Aux DO BEGIN IF Not Visitados[I] AND (G[Origen,I] <> Infinito) THEN Aux := Camino(G, I, Destino, Visitados); I := I + 1; END; END; Camino := Aux END; PROCEDURE TramoProblematico(G: TGrafo); VAR Visitados: TVisitados; I, J, K: TVertice; Aux: Integer; BEGIN FOR I := 1 TO N DO FOR J := 1 TO N DO IF (G[I, J] <> Infinito) THEN BEGIN FOR K := 2 TO N DO Visitados[K]:= False; Aux := G[I, J]; G[I, J] := Infinito; Visitados[1] := True; IF NOT Camino(G, 1, N, Visitados) THEN Writeln('Tramo problemático de ', I, ' a ', J); G[I, J] := Aux; END END; BEGIN … TramoProblematico(G); END. Universidad Politécnica de Madrid – E.U. Informática Página 3 3º) (3 Puntos) Dado un vector de N número enteros, determinar por medio de un algoritmo basado en el esquema de Divide y Vencerá cuál es la longitud máxima de la secuencia de números pares situados consecutivamente dentro de dicho vector. PROGRAM Problema3 (input, ouput); CONST N = …; TYPE tVector = ARRAY [1..N] OF Integer; FUNCTION Max(x, y: Integer): Integer; BEGIN IF x > y THEN Max := x ELSE Max := y END; (* Max *) FUNCTION SecuenciaPares(Vector: tVector; Iz, De: Integer; VAR LIzq, LDer: Integer): Integer; VAR Contador1, Contador2, LIz1, LIz2, LDe1, LDe2, Medio: Integer; BEGIN IF (De = Iz) THEN (* caso base *) IF Odd(Vector[De]) THEN BEGIN SecuenciaPares := 0; LIzq := 0; LDer := 0; END ELSE BEGIN SecuenciaPares := 1; LIzq := 1; LDer := 1; END ELSE BEGIN Medio := (De + Iz) DIV 2; Contador1 := SecuenciaPares(Vector, Iz, Medio, LIz1, LDe1); Contador2 := SecuenciaPares(Vector, Medio + 1, De, LIz2, LDe2); (* Combinación resultados *) LIzq := LIz1; LDer := LDe2; IF (LDe1 <> 0) AND (LIz2 <> 0) THEN BEGIN (* la secuencia continua *) Contador1 := Max(Contador1, LDe1 + LIz2); IF (LIz1 = Medio - Iz + 1) THEN LIzq := LIz1 + LDe2; IF (LDe2 = De - Medio) THEN LDer := LDe2 + LDe1; END; SecuenciaPares := Max(Contador1, Contador2) END END; (* SecuenciaPares *) PROCEDURE buscarSecuenciaPares(Vector: tVector; Iz, De: Integer); VAR LIz, LDe, LMax: Integer; BEGIN LMax := SecuenciaPares(Vector, Iz, De, LIz, LDe); WriteLn('La secuencia más larga mide: ', LMax); END; (* buscarSecuenciaPares *) PROCEDURE generarVector(VAR Vector: tVector); VAR i: Integer; BEGIN Randomize; FOR i := 1 TO N DO Vector[i] := Random(10); END; (* generarVector *) PROCEDURE mostrarVector(Vector: tVector); VAR i: Integer; BEGIN FOR i := 1 TO N DO Write(Vector[i]:3); END; (* mostrarVector *) VAR (* Programa Principal *) Vector: TVector; BEGIN generarVector(Vector); mostrarVector(Vector); buscarSecuenciaPares(Vector, 1, N) END. Universidad Politécnica de Madrid – E.U. Informática Página 4