Dpto. O.E.I. – U.P.M. ALGORÍTMICA 11/JUN/10 1º) (3’5 Puntos) Una empresa del sector químico dispone de N depósitos de líquido, de tal manera, que cada uno de ellos está identificado por un número entero en el intervalo comprendido entre 1 y N. Cada depósito tiene una capacidad para contener una cantidad de litros de pintura. Esta última información está almacenada en un vector de números reales de N posiciones. Los depósitos se han interconectado entre sí por medio de tuberías, formando una red que no tiene por qué ser conexa. Los gestores de la empresa desean saber cuánta pintura de un determinado color se puede almacenar en cada subconjunto de depósitos conectados directa o indirectamente entre sí. La red está almacenada en un grafo no dirigido representado con matriz de adyacencia. Se pide: Implementar un algoritmo en Pascal que determine la capacidad de cada subconjunto de depósitos que se encuentren conectados directa o indirectamente entre sí. CONST NMax = N; (* Número máximo de vértices *) TYPE tMatrizAdy = ARRAY [1..NMax, 1..NMax] OF Boolean; (* Matriz de Adyacencia *) tVisitados = ARRAY [1..NMax] OF Boolean; tVectorCapacidades = ARRAY [1..NMax] OF Integer; (* Se determina la capacidad de una componente conexa con un recorrido en profundidad *) FUNCTION Capacidad_CConexa(G: tMatrizAdy; vActual: Integer; VAR Visitados: tVisitados; VectorCap: tVectorCapacidades): Integer; VAR v: Integer; capacidad: Integer; BEGIN Visitados[vActual] := true; capacidad := VectorCap[vActual]; FOR v := 1 TO N DO IF (NOT Visitados[v]) AND G[vActual, v] THEN capacidad := capacidad + Capacidad_CConexa(G, v, Visitados, VectorCap); Capacidad_CConexa := capacidad END; (* Capacidad_CConexa *) PROCEDURE Capacidad_Depositos(G: tMatrizAdy; VectorCap: tVectorCapacidades) VAR v, cap: Integer; Visitados: tVisitados; BEGIN (* Inicializar Visitados *) FOR v := 1 TO N DO Visitados[v] := false; (* Se lanza un recorrido por cada componente conexa *) FOR v := 1 TO N DO IF NOT Visitados[v] THEN BEGIN cap := Capacidad_CConexa(G, v, Visitados, VectorCap); WriteLn('La componente conexa del vértice ', v, ' tiene una capacidad ', cap); END END; (* Capacidad_Depositos *) Universidad Politécnica de Madrid – E.U. Informática Página 1 2º) (3’5 Puntos) Dado un vector que contiene los valores ordenados del sistema monetario europeo, otro vector que almacena la cantidad disponible de cada valor y un importe a pagar. Se pide: Escribir un algoritmo en Pascal que determine cuantas formas distintas existen para pagar el importe utilizando el sistema monetario. PROGRAM FormasDePagarImporte; CONST N = 9; TYPE tIndice = 1 .. N; tSistemas = ARRAY[tIndice] OF Integer; tMonedas = ARRAY[tIndice] OF Integer; VAR Importe: Integer; Sistema: tSistemas; Monedas: tMonedas; Formas: Integer; PROCEDURE InicializarSistema(VAR Sistema: tSistemas); BEGIN Sistema[1] := 1; Sistema[2] := 2; Sistema[3] := 5; Sistema[4] := 10; Sistema[5] := 20; Sistema[6] := 50; Sistema[7] := 100; Sistema[8] := 200; Sistema[9] := 500 END; PROCEDURE InicializarMonedas(VAR Monedas: tMonedas); BEGIN Monedas[1] := 10; Monedas[2] := 10; Monedas[3] := 10; Monedas[4] := 10; Monedas[5] := 10; Monedas[6] := 10; Monedas[7] := 10; Monedas[8] := 10; Monedas[9] := 10 END; PROCEDURE EscribirSistema(Sistema: tSistemas); VAR I: tIndice; BEGIN FOR I := 1 TO N DO Write(Sistema[I]:3); WriteLn END; PROCEDURE EscribirMonedas(Monedas: tMonedas); VAR I: tIndice; BEGIN FOR I := 1 TO N DO Write(Monedas[I]:3); WriteLn END; Universidad Politécnica de Madrid – E.U. Informática Página 2 PROCEDURE CalcularFormasDePagar(Sistema: tSistemas; Monedas: tMonedas; Importe: Integer; Moneda: tIndice; VAR Formas: Integer); VAR Posibilidad: 0 .. N; BEGIN Posibilidad := Moneda - 1; REPEAT Posibilidad := Posibilidad + 1; IF (Monedas[Posibilidad] > 0) AND ((Importe - Sistema[Posibilidad]) >= 0) THEN BEGIN Importe := Importe - Sistema[Posibilidad]; Monedas[Posibilidad] := Monedas[Posibilidad] - 1; IF Importe = 0 THEN Formas := Formas + 1 ELSE CalcularFormasDePagar(Sistema, Monedas, Importe, Posibilidad, Formas); Importe := Importe + Sistema[Posibilidad]; Monedas[Posibilidad] := Monedas[Posibilidad] + 1; END UNTIL (Posibilidad = N) END; BEGIN InicializarSistema(Sistema); InicializarMonedas(Monedas); EscribirSistema(Sistema); EscribirMonedas(Monedas); Formas := 0; Importe := …; CalcularFormasDePagar(Sistema, Monedas, Importe, 1, Formas); Writeln('Valor total = ', Formas) END. Universidad Politécnica de Madrid – E.U. Informática Página 3 3º) (3 Puntos) En la guardería “culito feliz” los niños se han descalzado para dormir la siesta. Los cuidadores han recogido cada par de zapatos y los han metido en una caja. Antes de irse a casa, los niños tienen que recoger sus zapatos, pero como son pequeños no saben reconocerlos y necesitan ayuda. Un par de zapatos puede quedar pequeño, grande o encajar perfectamente en los pies de un solo niño. El objetivo de los cuidadores es realizar el reparto de los zapatos de una forma óptima por lo que se decide utilizar un programa informático de ayuda. Para ello, los N pares de zapatos y N niños se representan, respectivamente, mediante un subrango de 1 hasta N. Existe una función denominada comparaZapatos() que recibe dos pares de zapatos y devuelve 0, 1 ó 2 según sea el primer par de tamaño igual, menor ó mayor que el segundo. Existe otra función sirvenZapatosANiño() que recibe un par de zapatos y un niño y devuelve 0, 1 ó 2 según el par de zapatos le sirva perfectamente, le quede pequeño ó le quede grande al niño. Se pide: siguiendo el esquema Divide y Vencerás, implementar un algoritmo óptimo que empareje cada par de zapatos con su correspondiente niño suponiendo que cada par de zapatos sólo le sirve a un sólo niño. El resultado del emparejamiento debe devolverse en un vector de N posiciones donde el índice representa al niño i-ésimo y el contenido de una posición almacena el identificador del par de zapatos. CONST N = 9; TYPE Tzapatos = 1 .. N; Tbebes = 1 .. N; TvectorBebes = ARRAY[Tbebes] OF Integer (* Tbebes *); TvectorZapatos = ARRAY[Tzapatos] OF Integer (* Tzapatos *); VAR I: Integer; arrayZapatos: TvectorZapatos; arraySolucion: TvectorBebes; PROCEDURE Rapido(VAR Vector: TvectorZapatos); PROCEDURE Sort(Iz,De: Tzapatos); VAR I, J: Integer; Elemento1, Elemento2: Tzapatos; BEGIN I := Iz; J := De; Elemento1 := Vector[(Iz + De) DIV 2]; REPEAT WHILE comparaZapatos(Vector[I], Elemento1) = 1 DO I := I + 1; WHILE comparaZapatos(Elemento1, Vector[J]) = 1 DO J := J - 1; IF I <= J THEN BEGIN Elemento2 := Vector[I]; Vector[I] := Vector[J]; Vector[J] := Elemento2; I := I + 1; J := J - 1; END UNTIL I > J; IF Iz < J THEN Sort(Iz,J); IF I < De THEN Sort(I,De) END; BEGIN Sort(1, N); END; FUNCTION BuscarPar(arrayZapatos: TvectorZapatos; Bebe: Tbebes): Tzapatos; VAR Izq, Der, Cen: Integer; BEGIN Izq := 1; Der := N; REPEAT Cen := (Izq + Der) DIV 2; IF sirvenZapatosANinio(arrayZapatos[Cen], Bebe) = 1 THEN Izq := Cen + 1 ELSE IF sirvenZapatosANinio(arrayZapatos[Cen], Bebe) = 2 THEN Der := Cen - 1; UNTIL (sirvenZapatosANinio(arrayZapatos[Cen], Bebe) = 0) OR (Izq > Der); BuscarPar := arrayZapatos[Cen]; END; BEGIN FOR I := 1 TO N DO arrayZapatos[I] := I; Rapido(arrayZapatos); FOR I := 1 TO N DO arraySolucion[I] := BuscarPar(arrayZapatos, I); END. Universidad Politécnica de Madrid – E.U. Informática Página 4