Ascensor Peculiar: Resolución con Búsqueda en Anchura

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 contieneNenteros: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;
}

Etiquetas: BFS algoritmo de búsqueda grafo Resolución de Problemas C++

Publicado el 6-24 18:44