Solución - Universidad Politécnica de Madrid

Anuncio
Dpto. O.E.I. – U.P.M.
ALGORÍTMICA
14/ENE/11
1º) (3’5 Puntos) Se dispone de un tablero de 6×6 y seis conjuntos de seis fichas de distintos colores.
Se pide: Desarrollar un algoritmo en Pascal que sitúe las fichas en el tablero con las siguientes
restricciones:
 No pueden aparecer dos fichas del mismo color en la misma fila, ni en la misma columna
 No puede haber dos fichas del mismo color en ninguna casilla de las dos diagonales principales
 No puede haber dos fichas del mismo color en las cuatro casillas centrales del tablero.
En la figura aparece una posible solución al problema (representando los seis
colores de las fichas por los valores entre 0 y 5)
CONST
N = 6;
Vacio = 0;
TYPE
tTablero = ARRAY[1..N, 1..N] OF 0..N;
0
1
4
3
5
2
1
2
3
0
4
5
2
0
5
1
3
4
3
5
0
4
2
1
4
3
2
5
1
0
5
4
1
2
0
3
VAR
Tablero: tTablero;
I, J: Integer;
Solucion: Boolean;
PROCEDURE escribir(Tablero: tTablero);
VAR
I, J: Integer;
BEGIN
FOR I := 1 TO N DO BEGIN
FOR J := 1 TO N DO
Write(Tablero[I, J]:2);
WriteLn;
END
END;
FUNCTION Aceptable(Tablero: tTablero; Fila, Columna, Color: Integer): Boolean;
VAR
I: Integer; Correcto : Boolean;
BEGIN
Correcto := true; I := 1;
WHILE (I <= N) AND Correcto DO BEGIN
Correcto := (Tablero[Fila, I] <> Color) AND (Tablero[I, Columna] <> Color) AND
NOT ((Tablero[I, I] = Color) AND (Fila = Columna)) AND
NOT ((Tablero[I, N - I + 1] = Color) AND (Fila + Columna = (N + 1)));
I := I + 1
END;
Aceptable := Correcto
END;
PROCEDURE Ensayar(VAR Tablero: tTablero; Fila, Columna: Integer; VAR Solucion: Boolean);
VAR
Color: 0..N;
BEGIN
Columna := Columna + 1;
IF
Columna = (N + 1) THEN BEGIN
Fila := Fila + 1;
Columna := 1
END;
Color := 0;
REPEAT
Color := Color + 1;
IF
Aceptable(Tablero, Fila, Columna, Color) THEN BEGIN
Tablero[Fila, Columna] := Color;
IF (Fila = N) AND (Columna = N) THEN Solucion := TRUE
ELSE BEGIN
Ensayar(Tablero, Fila, Columna, Solucion);
IF NOT Solucion THEN Tablero[Fila, Columna] := Vacio;
END
END
UNTIL Solucion OR (Color = N);
END;
BEGIN
FOR I := 1 TO N DO
FOR J := 1 TO N DO Tablero[I, J] := Vacio;
Solucion := FALSE;
Ensayar(Tablero, 1, 0, Solucion);
IF Solucion THEN escribir(Tablero)
ELSE WriteLn('No existe solucion');
END.
Universidad Politécnica de Madrid – E.U. Informática
Página 1
2º) (3’5 Puntos) Se posee un mapa de carreteras que contiene 15 ciudades, y se pretende planificar
un viaje desde una ciudad de origen a una ciudad de destino. Dicho viaje deberá incluir
obligatoriamente la visita a tres ciudades intermedias previamente determinadas y nunca se visitará
una ciudad en más de una ocasión. Se sabe que el mapa es conexo.
Se pide: desarrollar un algoritmo en Pascal que muestre el camino más corto entre la ciudad origen y
la ciudad destino y que incluya las tres ciudades intermedias (en cualquier orden).
Para resolver el problema se dispondrá de una matriz de costes con las conexiones por carretera entre
las 15 ciudades. Las ciudades que no estén conectadas tendrán asignado el valor infinito en la
posición correspondiente de la matriz. Las ciudades intermedias vendrán marcadas en un vector de
booleanos.
CONST
N = 15;
{ Número de vértices del grafo }
INFINITO = MaxInt;
NO_VISITADO = -1;
TYPE
tCamino = ARRAY [1..N] OF Integer; { vector para almacenar caminos simples }
tVisitados = ARRAY [1..N] OF Boolean;
tMatrizCoste = ARRAY [1..N, 1..N] OF Integer;
FUNCTION RutaCompletada(Camino: tCamino; Intermedias: tVisitados; Origen, Destino: Integer): Boolean;
VAR
estaCompleta: Boolean;
v: Integer;
BEGIN
estaCompleta := (Camino[Origen] <> NO_VISITADO) AND (Camino[Destino] <> NO_VISITADO);
FOR v := 1 TO N DO
IF
Intermedias[v]
THEN estaCompleta := estaCompleta AND (Camino[v] <> NO_VISITADO);
RutaCompletada := estaCompleta
END;
PROCEDURE ImprimirCamino(Camino: tCamino; vOrigen, vActual: Integer);
BEGIN
IF
Camino[vActual] = vOrigen
THEN Write(vOrigen:2, ', ', vActual:2)
ELSE BEGIN
ImprimirCamino(Camino, vOrigen, Camino[vActual]);
Write(', ', vActual:2)
END
END;
{ P R O G R A M A
P R I N C I P A L }
FOR v := 1 TO N DO BEGIN
Intermedias[v] := false;
Visitados[v] := false;
caminoActual[v] := NO_VISITADO;
caminoOptimo[v] := NO_VISITADO;
END;
{ EJEMPLO: ciudades intermedias 5, 3 y 2 }
Intermedias[5] := true; Intermedias[3] := true; Intermedias[2] := true;
cActual := 0; cOptimo := INFINITO;
origen := 1;
destino := N;
caminoActual[origen] := origen;
PlanificarRuta(GNV, Intermedias, origen, origen, destino,
cActual, cOptimo, caminoActual, caminoOptimo);
IF
cOptimo <> INFINITO
THEN BEGIN
ImprimirCamino(caminoOptimo, origen, destino);
WriteLn(' Coste = ', cOptimo);
END
ELSE WriteLn('El problema no tiene solución')
Universidad Politécnica de Madrid – E.U. Informática
Página 2
PROCEDURE PlanificarRuta(GNV: tMatrizCoste; Intermedias: tVisitados;
origen, actual, destino: Integer; costeActual: Integer; VAR costeOptimo: Integer;
VAR caminoActual, caminoOptimo: tCamino);
VAR
v: Integer;
BEGIN
FOR v:= 1 TO N DO
IF (caminoActual[v] = NO_VISITADO) AND (GNV[actual, v] <> INFINITO)
THEN BEGIN
{ anotar }
caminoActual[v] := actual;
costeActual := costeActual + GNV[actual, v];
{ ¿es solución? }
IF
(v = destino) AND RutaCompletada(caminoActual, intermedias, origen, destino)
THEN BEGIN
IF
costeActual < costeOptimo
THEN BEGIN { copiar solución óptima }
costeOptimo := costeActual;
caminoOptimo := caminoActual;
END
END
ELSE
{ si el candidato coincide con el destino, no encontraremos solución }
IF
(costeActual < costeOptimo) AND (v <> destino)
THEN PlanificarRuta(GNV, Intermedias, origen, v, destino,
costeActual, costeOptimo, caminoActual, caminoOptimo);
{ desanotar }
caminoActual[v] := NO_VISITADO;
costeActual := costeActual - GNV[actual, v];
END
END;
Universidad Politécnica de Madrid – E.U. Informática
Página 3
3º) (3 Puntos) Dado un Grafo Árbol Dirigido (no valorado) del que se conoce el nodo raíz y
representado por listas de adyacencia, se pide: siguiendo el esquema Divide y Vencerás,
desarrollar en lenguaje Pascal un algoritmo que determine la altura del árbol.
CONST
N = 20;
TYPE
pNodo = ^tNodo;
tNodo = RECORD
Vertice: Integer;
Sig: pNodo;
END;
tListasAdy = ARRAY [1..N] OF pNodo;
tAlturas = ARRAY [1..N] OF Integer;
FUNCTION Maximo(V: tAlturas; Iz, De: Integer): Integer;
VAR
Medio, m1, m2: Integer;
BEGIN
IF
Iz = De
THEN Maximo := V[Iz]
ELSE
BEGIN
Medio := (Iz + De) DIV 2;
m1 := Maximo(V, Iz, Medio);
m2 := Maximo(V, Medio + 1, De);
IF
m1 > m2
THEN Maximo := m1
ELSE Maximo := m2
END
END;
{ Maximo }
FUNCTION AlturaArbol(VAR G: tListasAdy; vActual: Integer): Integer;
VAR
v, h, numDescendientes: Integer;
altura: tAlturas;
Aux: pNodo;
BEGIN
IF
G[vActual] = NIL
THEN h := 1
ELSE BEGIN
numDescendientes := 0;
Aux := G[vActual];
WHILE Aux <> NIL DO
BEGIN
numDescendientes := numDescendientes + 1;
altura[numDescendientes] := AlturaArbol(G, Aux^.Vertice);
Aux := Aux^.Sig;
END;
{ Combinar soluciones }
h := 1 + Maximo(altura, 1, numDescendientes);
END;
AlturaArbol := h;
END;
{ AlturaArbol }
{ P R O G R A M A
P R I N C I P A L
}
WriteLn('Altura del Árbol: ', AlturaArbol(G, Raiz));
Universidad Politécnica de Madrid – E.U. Informática
Página 4
Descargar