Solución - Universidad Politécnica de Madrid

Anuncio
Dpto. O.E.I. – U.P.M.
ALGORÍTMICA
08/JUN/12
1º) (3’5 Puntos) Dado un array que contiene N números naturales diferentes mayores que cero, y un
número X, se pide:
Se pide: desarrollar en Pascal una función que determine el número total de subconjuntos diferentes
cuya suma de sus elementos sea precisamente X.
CONST
N = 10;
TYPE
tVector = ARRAY [1..N] OF Integer;
VAR
V: tVector;
numSoluciones, X: Integer;
FUNCTION doSSXS(VAR V: tVector; X, actual, acumulado: Integer): Integer;
(* El vector se pasa por referencia exclusivamente para ahorrar memoria *)
VAR
i, numSoluciones: Integer;
BEGIN
numSoluciones := 0;
FOR i := actual TO N DO
IF V[i] + acumulado <= X
THEN BEGIN
V[i] := -V[i]; (* anotar (se hace sólo para mostrar el subconjunto) *)
IF
acumulado - V[i] = X THEN
NumSoluciones := NumSoluciones + 1
ELSE
NumSoluciones := NumSoluciones + doSSXS(V, X, i + 1, acumulado - V[i]);
V[i] := -V[i]
(* desanotar *)
END;
doSSXS := numSoluciones
END; (* doSSXS *)
FUNCTION SubSetXSum(V: tVector; X: Integer): Integer;
BEGIN
SubSetXSum := doSSXS(V, X, 1, 0)
END; (* SubSetSum *)
Universidad Politécnica de Madrid – E.U. Informática
Página 1
2º) (3’5 Puntos) Dado un grafo dirigido valorado (GDV) y un vector que contiene un valor asociado a
cada uno de los nodos de dicho grafo, se dice que un nodo es "neutral" si el valor asociado al nodo en
el vector es igual a la suma de los costes de los arcos entrantes y salientes en dicho nodo. Se dice que
un GDV es "equilibrado" si existe una cadena entre cada par de vértices del mismo y además todos
sus nodos son "neutrales".
Se pide: desarrollar un algoritmo en Pascal que determine si un GDV representado por listas de
adyacencia es "equilibrado".
NOTA: Como siempre, se deberá prestar atención a la complejidad de la solución desarrollada.
CONST
Infinito = 999999;
NoVisitado = -1;
TYPE
TVertice = 1..N;
TGrafo = ARRAY [TVertice, TVertice] OF LongInt;
TVertices = ARRAY [TVertice] OF TVertice;
TMenorCoste = ARRAY [TVertice] OF LongInt;
TVisitados = ARRAY [TVertice] OF Boolean;
PROCEDURE recalculaValores(VAR Valores: tValores; GDV: tGrafo);
VAR
i: Integer;
Aux: tListaAdy;
BEGIN (* descuenta los valores de los costes de los arcos *)
FOR i := 1 TO N DO BEGIN
Aux := GDV[i];
WHILE (Aux <> NIL) DO BEGIN
Valores[i] := Valores[i] - Aux^.Coste; (* arco saliente *)
Valores[Aux^.Adyacente] := Valores[Aux^.Adyacente] - Aux^.Coste;
Aux := Aux^.Sig
END
END
END; (* recalculaValores *)
(* arco entrante *)
FUNCTION Conectado(GDV: tGrafo; Origen, Destino: tVertice): Boolean;
VAR
Encontrado: Boolean;
Aux: tListaAdy;
BEGIN
Encontrado := False;
Aux := GDV[Origen];
WHILE NOT Encontrado AND (Aux <> NIL) DO BEGIN
Encontrado := (Aux^.Adyacente = Destino);
Aux := Aux^.Sig
END;
Conectado := Encontrado
END; (* Conectado *)
PROCEDURE Visitar2(Origen: tVertice; GDV: tGrafo; VAR Visitados: tVisitados);
VAR
i: tVertice;
BEGIN
Visitados[Origen] := True;
FOR i := 1 TO N DO
IF
Not Visitados[i] AND (Conectado(GDV, Origen, i) OR Conectado(GDV, i, Origen))
THEN
Visitar2(i, GDV, Visitados)
END; (* Visitar2 *)
Universidad Politécnica de Madrid – E.U. Informática
Página 2
FUNCTION TodosVisitadosYNeutrales(Visitados: tVisitados; Valores: tValores):Boolean;
VAR
i:Integer;
Ok:Boolean;
BEGIN
Ok := True;
i := 1;
WHILE (i <= N) AND Ok DO BEGIN
Ok := Visitados[i] AND (Valores[i] = 0);
i := i + 1
END;
TodosVisitadosYNeutrales := Ok
END; (*TodosVisitadosYNeutrales *)
FUNCTION Equilibrado(GDV: tGrafo; Valores: tValores): Boolean;
VAR
Visitados : tVisitados;
i : tVertice;
BEGIN
recalculaValores(Valores, GDV);
FOR i := 1 TO N DO
Visitados[i] := False;
Visitar2(1, GDV, Visitados);
Equilibrado := TodosVisitadosYNeutrales(Visitados, Valores)
END; (* Equilibrado *)
Universidad Politécnica de Madrid – E.U. Informática
Página 3
3º) (3 Puntos) Dado un vector que contiene N números enteros, se pide: siguiendo el
esquema Divide y Vencerás, desarrollar en lenguaje Pascal un algoritmo que determine la
posición dentro del vector, si existe, de dos elementos consecutivos que cumplan las
siguientes condiciones: ambos poseen el mismo signo y además su suma -en valor absolutoes máxima. Si no existen, devolverá el valor -1. Ejemplo:
1
-2
20
-20
2
3
-3
-10
2
3
4
1
2
3
4
5
6
7
8
9
10
11
Deberá devolver 7, que corresponde a los valores -3 y -10 del vector.
CONST
N = ???;
TYPE
tVector = ARRAY [1..N] OF Integer;
FUNCTION SumaMaxima(VAR Vector: tVector; Iz, De: Integer; VAR suma: Integer): Integer;
VAR
ind1, ind2, sum1, sum2, Medio, maximo: Integer;
BEGIN
IF
De = Iz (* caso base *)
THEN BEGIN
SumaMaxima := -1;
suma := -1;
END
ELSE BEGIN
Medio := (De + Iz) DIV 2;
ind1 := SumaMaxima(Vector, Iz, Medio, sum1);
ind2 := SumaMaxima(Vector, Medio + 1, De, sum2);
(* Combinación resultados *)
IF sum1 > sum2
THEN BEGIN
suma := sum1;
maximo := ind1;
END
ELSE BEGIN
suma := sum2;
maximo := ind2
END;
IF
((Vector[Medio] >= 0) AND (Vector[Medio + 1] >= 0)) OR
((Vector[Medio] < 0) AND (Vector[Medio + 1] < 0))
THEN
IF Abs(Vector[Medio] + Vector[Medio + 1]) > suma
THEN BEGIN
suma := Abs(Vector[Medio] + Vector[Medio + 1]);
maximo := Medio
END;
SumaMaxima := maximo
END
END; (* SumaMaxima *)
(* secuencia *)
PROCEDURE buscarSumaMaxima(Vector: tVector; Iz, De: Integer);
VAR
indMax, sum: Integer;
BEGIN
indMax := SumaMaxima(Vector, Iz, De, sum);
WriteLn;
IF
indMax = -1
THEN
WriteLn('No hay ninguna secuencia')
ELSE
WriteLn('La secuencia está en la posición: ', indMax);
END; (* buscarSumaMaxima *)
Universidad Politécnica de Madrid – E.U. Informática
Página 4
Descargar