Está en la página 1de 6

Universidad de Alcalá

Departamento de Ciencias de la Computación


Algoritmia y Complejidad
Grado en Ingeniería Informática

EJERCICIOS DE BACKTRACKING
Ejercicio 1). Se tienen N elementos distintos almacenados en una estructura de acceso
directo (por ejemplo, un vector con los números 1, 2, 3, 4 y 5, o la cadena “abcdefg”) y
se quiere obtener todas las formas distintas de colocar esos elementos, es decir, hay que
conseguir todas las permutaciones de los N elementos. Diseñar un algoritmo que use
Backtracking para resolver el problema.
Ejercicio 2). Resolver el problema anterior considerando la posibilidad de que los
elementos se repitan entre sí (por ejemplo, el vector 1, 2, 1, 3, 2 o la cadena “acabada”).
Ejercicio 3). Se tiene un sistema de billetes de distintos valores y ordenados de menor a
mayor (por ejemplo 1, 2, 5, 10, 20, 50 y 100 euros), que se representan mediante los valores
vi, con i  {1, …, N} (en el caso anterior, N = 7) de manera que de cada billete se tiene una
cantidad finita, mayor o igual a cero, que se guarda en ci (siguiendo con el ejemplo, c3 = 6
representaría que hay 6 billetes de 5 euros).
Se quiere pagar exactamente una cierta cantidad de dinero D, utilizando para ello la menor
n
cantidad de billetes posible. Se sabe que D   ci vi , pero puede que la cantidad exacta D
i 1
no sea obtenible mediante los billetes disponibles.
Diseñar un algoritmo con la metodología Backtracking que determine, teniendo como datos
los valores ci, vi y D,
 si la cantidad D puede devolverse exactamente o no, y
 en caso afirmativo, cuántos billetes de cada tipo se necesitan para el óptim.
Ejercicio 4). Se tiene un número de Tam cifras almacenado en una cadena de texto; por
ejemplo, la cadena dato = 1151451. Diseñar un algoritmo que mediante técnicas de
Backtracking encuentre, de la manera más eficiente posible, todos los números distintos de
N cifras que puedan formarse con los números de la cadena sin alterar su orden relativo
dentro de la misma. Por ejemplo, si N = 4, son números válidos 1151, 1511 y 1541, pero
no 4551 o 5411 que aunque pueden formarse con los dígitos de la cadena dato implican
una reordenación.
Ejercicio 5). Se dispone de un tablero M de tamaño FxC (F es la cantidad de filas y C la
cantidad de columnas) y se pone en una casilla inicial (posx, posy) un caballo de ajedrez. El
objetivo es encontrar, si es posible, la forma en la que el caballo debe moverse para recorrer
todo el tablero de manera que cada casilla se utilice una única vez en el recorrido (el tablero
8x8 siempre tiene solución independientemente de dónde comience el caballo). El caballo
puede terminar en cualquier posición del tablero.
Un caballo tiene ocho posibles movimientos (suponiendo, claro está, que no se sale del
tablero). Un movimiento entre las casillas Mij y Mpq es válido solamente si
 ( | p – i | = 1 ) && ( | q – j | = 2 ), o bien si
 ( | p – i | = 2 ) && ( | q – j | = 1 ),
es decir, una coordenada cambia dos unidades y la otra una única unidad.

Jesús Lázaro García Pág. 1 / 6


Universidad de Alcalá
Departamento de Ciencias de la Computación
Algoritmia y Complejidad
Grado en Ingeniería Informática

En el siguiente ejemplo se muestran las ocho posibles casillas a las que puede “saltar” un
caballo, numeradas de 1 a 8.
8 1
7 2
C
6 3
5 4
Diseñar un algoritmo con metodología Backtracking que, teniendo como datos los valores
F, C, posx y posy genere la sucesión de casillas que permite al caballo recorrer todo el
tablero sin utilizar más de una vez la misma casilla.
Nota: puede ser útil crear un vector de movimientos para generalizar el tratamiento de los
casos con un bucle, por ejemplo
tipos tmovimiento = vector[1..8] de registro
incx, incy: entero
freg
var mov: tmovimiento
mov[1].incx = 1; mov[1].incy = 2
mov[2].incx = 2; mov[2].incy = 1
(...)
mov[8].incx = –1; mov[8].incy = 2
Ejercicio 6). Resolver el problema anterior añadiendo como requisito que el caballo
termine en la casilla en la que comenzó el recorrido.
Ejercicio 7). Se ha recibido un mensaje de texto, aunque está codificado como el valor
numérico codigo = 903900439651484; se sabe que cada dígito de codigo se
corresponde con una letra distinta, pero no se sabe cuál. Obviamente, para poder
descodificarlo se necesita la tabla de conversión entre letras y dígitos.
Para obtener la relación existente entre letras y números hay que resolver la siguiente suma:
H A R R Y
+ P O T T E R
-------------
T R O L L S
sabiendo que:
 Cada letra es una única cifra para todo el problema. Por ejemplo, si la letra
“R” fuese “3” este dato valdría para todas las “R” de las palabras HARRY,
POTTER y TROLLS, y además el “3” del mensaje codigo se sustituiría por
la letra “R”.
 Cuando las letras de la suma se sustituyen por su valor, la operación
aritmética debe ser correcta. Es decir, no es posible que “Y” valga 1, “R”
valga 2 y “S” valga 8.
 Los números que aparecen en la suma no pueden empezar por “0”.
 Solo existe una solución al problema.

Jesús Lázaro García Pág. 2 / 6


Universidad de Alcalá
Departamento de Ciencias de la Computación
Algoritmia y Complejidad
Grado en Ingeniería Informática

Diseñar un algoritmo que mediante técnicas de Backtracking encuentre, de forma eficiente


en la medida posible, la tabla de conversión entre letras y dígitos necesaria para poder
descodificar el mensaje codigo.
Ejercicio 8). Se tiene una caja de tamaño 3x5 en la que hay que meter una serie de piezas
de madera, que tienen tamaños 1x1, 1x2, 2x1, 2x2, 1x3 y 3x1. Una representación gráfica
del problema puede ser la siguiente:

Las piezas deben ser usadas conforme a su tamaño, es decir, no pueden girarse

Una posible solución al problema puede ser la siguiente:

Diseñar un algoritmo que encuentre todas las formas de rellenar la caja usando técnicas de
Backtracking.
Ejercicio 9). Repetir el ejercicio anterior, pero permitiendo que las piezas giren. Una
posible solución para este problema sería la siguiente:

Se puede observar que este rellenado de la caja no hubiese sido una solución para el
problema anterior al tener giros de piezas.

Ejercicio 10). Se dispone de una tabla laberinto[1..n,1..m] con valores lógicos que
representa un laberinto. El valor TRUE indica la existencia de una pared (no se puede
atravesar), mientras que FALSE representa una casilla recorrible. Para moverse por el
laberinto, a partir de una casilla se puede desplazar horizontal o verticalmente, pero solo a
una casilla vacía (FALSE). Los bordes de la tabla están completamente a TRUE excepto
una casilla, que es la salida del laberinto. Diseñar un algoritmo Backtracking que encuentre
todos los caminos posibles que llevan a la salida desde una casilla inicial determinada, si es
posible salir del laberinto.

Jesús Lázaro García Pág. 3 / 6


Universidad de Alcalá
Departamento de Ciencias de la Computación
Algoritmia y Complejidad
Grado en Ingeniería Informática

Ejemplos: █ representa una celda de la matriz con valor TRUE; ○ es la posición inicial.
███████ ███████
█ █
█○█ █ █ █○█ █ █
█ █ █ █ █ █
███ █ ███ █
███████ ███████

███████ ███████
█ █
█○█ █ █ █○█ █ █
█ █ █ █ █ █
███ █ ███ █
███████ ███████
Ejercicio 11). (Examen Junio 2013. 3 puntos) Se están organizando las elecciones en
Abecelandia, ciudad famosa por sus bellas plazas y que ya conoces, y desde el
ayuntamiento se prepara el sistema electoral.
Cada habitante de Abecelandia puede votar una única vez, y para llevar el control de
asistencia los votantes reciben un código personal formado por 2 listas de N números, cada
uno de ellos con un valor entre 0 y N. Por ejemplo, con N = 3 un código podría ser (0, 3, 2)
y (2, 1, 2).
Como en Abecelandia están acostumbrados a las letras y no a los números cada
0
ciudadano recibe una tarjeta impresa con una matriz de puntos de tamaño NxN y
que representa su código para que pueda ser leído electrónicamente. La matriz 3
está configurada de tal forma que la cantidad de puntos de cada fila se 2
corresponde con los valores de la primera lista del código, y la cantidad de
puntos de cada columna coincide con los de la segunda lista. El código anterior 2 1 2
se representaría entonces como… (ver matriz a la derecha):
En el ayuntamiento han detectado que no todas las listas de códigos permiten generar una
matriz única, y les preocupa que el proceso electoral se invalide. Por ejemplo, para N = 3 el
código formado por (1, 2, 1) (1, 2, 1) puede representarse, entre otras formas, como…

Diseñar un algoritmo con metodología Backtracking, intentando que sea lo más eficiente
posible, que determine si un código personal tiene una representación matricial única o no.
Los datos del problema son el valor N (puede considerarse conocido en todo el algoritmo) y
las dos estructuras que guardan los valores numéricos.

Jesús Lázaro García Pág. 4 / 6


Universidad de Alcalá
Departamento de Ciencias de la Computación
Algoritmia y Complejidad
Grado en Ingeniería Informática

Ejercicio 12). En el Colegio de Magia y Hechicería han recibido un mensaje codificado en


el antiguo Morse Mágico, donde las letras estaban codificadas mediante una sucesión de
símbolos + y – que es única para cada letra (ver tabla al final del ejercicio). El mensaje
codificado que han recibido es el siguiente: “+-+++++-+-++”.
Si el Morse Mágico no se usa en la actualidad es por una buena razón: al inventarlo no
tuvieron en cuenta la separación de códigos, lo que hace que el mismo mensaje pueda ser
decodificado de numerosas (por no decir numerosisísimas) formas. Por ejemplo, el mensaje
anterior podría ser “PARRA”, “SIESTA”, “REMO”, “SI#IBA”, “CANSO”, “CESTA”,
“SIERRA”, “PASTA”… y por supuesto, cosas como “SWNP” o “C#JS”.
Diseñar un algoritmo que permita obtener todas las decodificaciones posibles a partir de un
mensaje codificado (dato de entrada al algoritmo) con Morse Mágico. El algoritmo deberá
ser lo más eficiente posible debido al alto número de posibilidades.

TABLA DE DESCODIFICACIÓN

+ S -++ O +--+ K
- B -+- T +--- Q
++ A --+ X -+++ W
+- R --- L -++- !
-+ I ++++ # -+-+ J
-- D +++- Y -+-- V
+++ E ++-+ M --++ ?
++- N ++-- U --+- H
+-+ C +-++ P ---+ Z
+-- . +-+- F ---- G
Ejercicio 13). (Examen Enero 2014. 3 puntos) El arqueólogo y aventurero Indiana Croft se
encuentra en Busca de la Cuna de la Vida, y finalmente la ha encontrado en el Templo
Maldito. El problema es que le esperan un montón de habitaciones llenas de trampas…
como ésta.

Indiana Croft está en una sala cuadrada de 64 m2 (es decir, 0 0 0 1 2 2 3 2
de forma 8 x 8) donde cada piedra del suelo (cuadradas, de
1 x 1 metros) tiene un número escrito (0, 1, 2 ó 3). 0 0 1 0 1 0 2 2
Siguiendo las instrucciones que aparecen en un antiguo 1 2 3 2 2 0 0 0
diario, Indiana Croft sabe que el número de cada baldosa 0 0 0 0 3 3 2 2
representa la cantidad de veces que puede ser pisada antes 0 1 1 2 2 0 0 2
de que se cierre automáticamente la puerta de la
1 3 0 0 1 1 1 3
habitación. Aún más, el diario también especifica que para
poder abrir la salida de la sala es necesario pisar todas las 0 2 1 1 1 1 0 1
baldosas exactamente el número de veces que tienen 0 2 1 0 1 1 0 0
grabado. Para poder volver a pisar una baldosa es 
necesario haber estado en otra antes (es decir, no se puede

Jesús Lázaro García Pág. 5 / 6


Universidad de Alcalá
Departamento de Ciencias de la Computación
Algoritmia y Complejidad
Grado en Ingeniería Informática

“saltar” en vertical sobre la misma piedra para conseguir pisarla varias veces; es necesario
cambiar de baldosa); Indiana Croft solo puede desplazarse de una baldosa a otra que esté
adyacente en horizontal o vertical.
Afortunadamente, Indiana Croft puede contactar contigo por radio, y te ha dictado los
números de todas las baldosas, que son los que aparecen en la tabla adjunta, así como la
posición de la entrada () y de la salida () de la habitación. Debes diseñar un algoritmo
que encuentre una forma de abrir la puerta de manera que Indiana Croft pueda salir por ella.

Jesús Lázaro García Pág. 6 / 6