Camino del soldado en el río

Enunciado

Enlace al problema Descripción del problema

Hay un soldado en el punto A del tablero, que necesita llegar al punto B. El movimiento del soldado es hacia abajo o hacia la derecha. En el tablero hay un caballo en el punto C, y los puntos alcanzables por el caballo se consideran puntos de control. Este problema se conoce como "el caballo bloquea al soldado".

El tablero se representa con coordenadas, donde A está en (0,0) y B está en (n,m), con n y m no mayores a 20. La posición del caballo también debe proporcionarse.

Se pide calcular el número de caminos posibles desde A hasta B, asumiendo que el caballo no se mueve.


Formato de entradda

Una línea con cuatro valores: las coordenadas de B y las del caballo.


Formato de salida

Un valor que representa el número total de caminos.


Ejemplo de entrada/salida

Entrada #1
6 6 3 3
Salida #1
6


Nota

El resultado puede ser muy grande.


------------------------------------------------


Análisis

Este problema requiere calcular el número de caminos posibles para un soldado que se mueve solo hacia abajo o hacia la derecha, evitando ciertos puntos controlados por un caballo.

Por ejemplo, en el caso del ejemplo, algunos puntos son inválidos:

  0 1 2 3 4 5 6---coordenadas horizontales
0 A 0 0 0 0 0 0
1 0 0 N 0 N 0 0
2 0 N 0 0 0 N 0
3 0 0 0 C 0 0 0
4 0 N 0 0 0 N 0
5 0 0 N 0 N 0 0
6 0 0 0 0 0 0 0
|-coordenadas verticales


Podemos definir una matriz dp[i][j], donde dp[i][j] representa el número de caminos desde A hasta el punto (i,j). La fórmula para calcular esto es:

dp[i][j] = dp[i-1][j] + dp[i][j-1]


Expliccación: Para llegar a un punto, solo se puede venir desde arriba o desde la izquierda, por lo que la suma de ambos da el número total de caminos.

Para evitar problemas en los bordes, se ajustan las coordenadas sumando 1 a cada una. Además, se inicializa dp[0][1] = 1.

Programa

Implementamso el enfoque de dinámica programada:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int bx, by, cx, cy;
unsigned long long dp[25][25];
bool f[25][25];

const int fx[9] = {0, -2, -1, 1, 2, 2, 1, -1, -2};
const int fy[9] = {0, 1, 2, 2, 1, -1, -2, -2, -1};

int main() {
    scanf("%d%d%d%d", &bx, &by, &cx, &cy);
    bx++; by++; cx++; cy++;
    dp[0][1] = 1;

    for(int i = 0; i < 9; i++)
        f[cx + fx[i]][cy + fy[i]] = true;

    for(int i = 1; i <= bx; i++)
        for(int j = 1; j <= by; j++)
            dp[i][j] = (dp[i-1][j] + dp[i][j-1]) * (!f[i][j]);

    printf("%lld\n", dp[bx][by]);
    return 0;
}


Etiquetas: programación_dinámica Matrices caminos algoritmos estructuras_de_datos

Publicado el 10-17 03:47