Existe un edificio conNpisos. Cada pisoitiene asociado un valorKi(0 ≤Ki<=N). Un ascensor especial opera en este edificio con solo dos botones: "Subir" y "Bajar".
Al estar en el pisoi, si se presiona el botón "Subir", el ascensor se moveráKipisos hacia arriba, llegando al pisoi + Ki. De manera similar, al presionar "Bajar", el ascensor se desplaazráKipisos hacia abajo, alcanzando el pisoi - Ki.
Existen restricciones: el ascensor no puede superar el pisoNni descender por debajo del piso 1.
El objetivo es determinar la cantidad mínima de operaciones (pulsaciones de botones) necesarias para ir desde un piso de inicioAhasta un piso de destinoB.
Entrada
La entrada consiste en varios casos de prueba. Cada caso se describe en dos líneas:
- La primera línea contiene tres enteros:
N(número total de pisos),A(piso de inicio) yB(piso de destino). Los valores están en el rango 1 ≤N,A,B≤ 200. - La segunda línea contiene
Nenteros:k1,k2, ...,kN, dondekies el valor asociado al pisoi.
La entrada finaliza con un caso dondeNes 0.
Salida
Para cada caso de prueba, se debe imprimir un entero que represente el número mínimo de pulsaciones de botones para ir deAaB. Si el pisoBes inalcanzable desdeA, se debe imprimir -1.
Ejemplo de Entrada
5 1 5
3 3 1 2 5
0
Ejemplo de Salida
3
Implementación (C++)
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int MAXN = 205;
int n_pisos, piso_destino;
int valores_k[MAXN];
bool visitado[MAXN];
struct Estado {
int piso_actual;
int pasos;
};
int resolver_ascensor() {
queue<Estado> q_bfs;
Estado estado_inicial = {0, 0}; // piso_inicial se asignará en main
// Inicializar el estado inicial
// Asumimos que el piso de inicio 'a' se pasa como parámetro o se accede globalmente
// Aquí lo inicializamos con un valor placeholder y lo corregiremos en main.
estado_inicial.piso_actual = 0; // Se establecerá en main
estado_inicial.pasos = 0;
q_bfs.push(estado_inicial);
memset(visitado, false, sizeof(visitado));
while (!q_bfs.empty()) {
Estado actual = q_bfs.front();
q_bfs.pop();
// Marcar el piso actual como visitado para evitar ciclos
visitado[actual.piso_actual] = true;
// Si hemos llegado al piso de destino, retornamos el número de pasos
if (actual.piso_actual == piso_destino) {
return actual.pasos;
}
// Explorar las dos posibles acciones: subir y bajar
for (int direccion : {-1, 1}) { // -1 para bajar, 1 para subir
int siguiente_piso = actual.piso_actual + direccion * valores_k[actual.piso_actual];
int siguientes_pasos = actual.pasos + 1;
// Verificar si el siguiente piso es válido y no ha sido visitado
if (siguiente_piso >= 1 && siguiente_piso <= n_pisos && !visitado[siguiente_piso]) {
Estado siguiente_estado = {siguiente_piso, siguientes_pasos};
q_bfs.push(siguiente_estado);
}
}
}
// Si la cola se vacía y no se ha alcanzado el destino, es inalcanzable
return -1;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int piso_inicial;
while (cin >> n_pisos && n_pisos) {
cin >> piso_inicial >> piso_destino;
for (int i = 1; i <= n_pisos; ++i) {
cin >> valores_k[i];
}
// Establecer el piso de inicio real para la búsqueda
Estado estado_inicial_real = {piso_inicial, 0};
queue<Estado> q_bfs_real;
q_bfs_real.push(estado_inicial_real);
memset(visitado, false, sizeof(visitado));
int resultado = -1; // Inicializar resultado
while (!q_bfs_real.empty()) {
Estado actual = q_bfs_real.front();
q_bfs_real.pop();
if (actual.piso_actual == piso_destino) {
resultado = actual.pasos;
break; // Encontramos la ruta más corta
}
// Marcar solo si no ha sido visitado previamente
if (!visitado[actual.piso_actual]) {
visitado[actual.piso_actual] = true;
// Calcular piso de subida
int piso_subida = actual.piso_actual + valores_k[actual.piso_actual];
if (piso_subida >= 1 && piso_subida <= n_pisos && !visitado[piso_subida]) {
q_bfs_real.push({piso_subida, actual.pasos + 1});
}
// Calcular piso de bajada
int piso_bajada = actual.piso_actual - valores_k[actual.piso_actual];
if (piso_bajada >= 1 && piso_bajada <= n_pisos && !visitado[piso_bajada]) {
q_bfs_real.push({piso_bajada, actual.pasos + 1});
}
}
}
cout << resultado << endl;
}
return 0;
}