Определить, сколько существует различных маршрутов, ведущих из левого верхнего в правый нижний угол - Free Pascal

Узнай цену своей работы

Формулировка задачи:

Дана прямоугольная доска N × M (N строк и M столбцов). В левом верхнем углу находится шахматный конь, которого необходимо переместить в правый нижний угол доски. При этом конь может ходить только так, как показано на рисунке: Необходимо определить, сколько существует различных маршрутов, ведущих из левого верхнего в правый нижний угол.
Входные данные В первой строке входного файла находятся два натуральных числа N и M (1 ≤ N, M ≤ 15).
Выходные данные В выходной файл выведите единственное число количество способов добраться конём до правого нижнего угла доски.
Примеры входные данные 4 4 выходные данные 2 входные данные 7 15 выходные данные 13309
Пробовал решить так:
Листинг программы
  1. read(n,m);
  2. a[1,1]:=1;
  3. a[0,3]:=1;
  4. a[3,0]:=1;
  5. For i:=1 to 15 do
  6. For j:=1 to 15 do
  7. a[i,j]:=a[i+1,j-2]+a[i-1,j-2]+a[i-2,j-1]+a[i-2,j+1];
  8. write(a[n,m]);
...но ничего не получилось, уже два часа бьюсь, не могу понять, что не так.

Решение задачи: «Определить, сколько существует различных маршрутов, ведущих из левого верхнего в правый нижний угол»

textual
Листинг программы
  1. {$mode objfpc}
  2. {$COPERATORS ON} //Чтобы можно было использовать +=
  3. const MaxSize = 15;
  4. var dp: array [1..MaxSize, 1..MaxSize] of int64;// Насколько я помню ответ там большой можем быть, потому лучше взять int64
  5.     n, m: Integer;
  6.    
  7. function answer(i, j: Integer): int64;
  8. begin
  9.    if dp[i][j] >= 0 then Exit(dp[i][j]);
  10.    { Будем считать что если dp[i][j] = -1, то мы его еще не считали, а если мы уже считали это значение, тогда
  11.      возвращаем его и выходим из функции}
  12.    dp[i][j] := 0;
  13.    if i-2 >= 1 then begin // Проверяем границы чтоб не обратиться к элементу которого нет
  14.       if j-1 >= 1 then dp[i][j] += answer(i-2, j-1); // прибавляем ответ
  15.       if j+1 <= m then dp[i][j] += answer(i-2, j+1);
  16.    end;
  17.    if j-2 >= 1 then begin
  18.       if i-1 >= 1 then dp[i][j] += answer(i-1, j-2);
  19.       if i+1 <= n then dp[i][j] += answer(i+1, j-2);
  20.    end;
  21.    Result := dp[i][j];
  22. end;
  23.  
  24. var i, j: Integer;
  25. begin
  26.    Readln(n, m);
  27.    for i := 1 to n do
  28.       for j := 1 to m do
  29.          dp[i][j] := -1; // Изначально все пометим -1
  30.    dp[1][1] := 1; // Кроме начального значения
  31.    Write(answer(n, m));
  32. end.

Объяснение кода листинга программы

  1. Входные данные: n, m (размеры сетки)
  2. Создание массива dp для хранения промежуточных результатов
  3. Инициализация всех элементов dp[-1, -1] = -1 (помечаем как не просчитанные)
  4. Инициализация начального элемента dp[1][1] = 1
  5. Функция answer: рекурсивный подсчет количества путей от левого верхнего до правого нижнего угла
  6. Проверка базового случая: если dp[i][j] уже есть, то возвращаем его и выходим из функции
  7. Рекурсивный вызов функции answer для четырех соседей элемента i, j (вверх, вниз, влево, вправо)
  8. Суммируем результаты рекурсивных вызовов
  9. Возвращаем итоговое значение dp[i][j]
  10. Заполнение массива dp значениями от 1 до n*m (помечаем как просчитанные)
  11. Вывод результата в консоль

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 3.818 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы