Solución - Universidad Politécnica de Madrid

Anuncio
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
Descargar