Решение о путешествии Найта дает неправильный результат?

Путешествие рыцарей, в котором нам указаны начальная/конечная точки и размер доски (n*n):

Найдите минимальные шаги, чтобы добраться до конца от начальной точки. Если пути нет, верните -1:

Решение о путешествии Найта дает неправильный результат?

Я пробовал решить эту проблему с помощью DFS:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Cell {
public:
    int x, y;
    Cell(int x, int y) {
        this->x = x;
        this->y = y;
    }
};

int count(vector<vector<int>>& board, int a, int b, int x, int y, int n) {
    if (a >= n || b >= n || b < 0 || a < 0 || board[a][b] == 1) return 500;
    if (a == x && b == y) return 0;

    
    board[a][b] = 1;

    int one = count(board, a + 2, b + 1, x, y, n) + 1; 
    int two = count(board, a + 2, b - 1, x, y, n) + 1; 
    int three = count(board, a - 2, b + 1, x, y, n) + 1; 
    int four = count(board, a - 2, b - 1, x, y, n) + 1; 
    int five = count(board, a + 1, b + 2, x, y, n) + 1; 
    int six = count(board, a + 1, b - 2, x, y, n) + 1; 
    int seven = count(board, a - 1, b + 2, x, y, n) + 1; 
    int eight = count(board, a - 1, b - 2, x, y, n) + 1; 

    board[a][b] = 0;

    int minMoves = min({one, two, three, four, five, six, seven, eight});
    
    return minMoves;
}

int minMovesRequired(int n, Cell start, Cell end) {
    vector<vector<int>> board(n, vector<int>(n, 0));
    int a = start.x-1;
    int b = start.y-1;
    int c = end.x-1;
    int d = end.y-1;
    int ans = count(board, a, b, c, d, n);

    return (ans >= 500) ? -1 : ans;
}

int main() {
    int n = 6;
    Cell start(6, 1); 
    Cell end(2, 4); 

    int result = minMovesRequired(n, start, end);
    cout << "Minimum moves required: " << result << endl;

    return 0;
}

... но для этого ввода:

n: 6 
start: 6, 1 
end: 2, 4

... Я не получаю ожидаемого результата:

  • ожидаемый результат: 3
  • фактический вывод кода: tle

Как мне вообще подойти к этому вопросу? Почему это неправильно?

Добро пожаловать в Stack Overflow. Пожалуйста, прочитайте справочный центр , пройдите экскурсию SO и прочитайте Как задать вопрос . Также, пожалуйста, прочитайте о как написать «идеальный» вопрос , особенно о его контрольном списке . Затем отредактируйте свой вопрос, чтобы улучшить его, например, расскажите нам о своей проблеме.

Some programmer dude 08.07.2024 13:44

Ваши координаты отсчитываются от единицы, а ваша «проверка безопасности» отсчитывается от нуля, поэтому count возвращает 500 немедленно, поскольку a == n при первом вызове.

molbdnilo 08.07.2024 14:33

изменил значения координат на индекс, отсчитываемый от нуля, int a=start.x-1; интервал b=start.y-1; интервал c=end.x-1; интервал d=end.y-1; теперь это дает результат.

new 08.07.2024 14:44

Похоже, вы используете DFS вместо BFS, что лучше решает вашу проблему. Кроме того, вы смешали индексацию на основе 1 с индексацией на основе 0, что привело к некоторым проблемам.

Marek R 08.07.2024 16:09

Если вы используете DFS, вам фактически придется просмотреть КАЖДЫЙ маршрут от начала до конца, а затем найти лучший из них. Используйте BFS, и вы быстро посетите каждую клетку на доске и сможете остановиться, как только дойдете до конца. Вместо этого попробуйте решить проблему с помощью BFS.

lastchance 09.07.2024 15:09

На workat.tech вы отправляете свой код?

trincot 10.07.2024 16:28

Да, я решал эту проблему в Work at Tech.

new 13.07.2024 23:22

Хорошо. Вы проверили мой ответ?

trincot 14.07.2024 08:04
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
8
176
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не получаю ожидаемый результат: ожидаемый результат: 3, фактический вывод кода: tle

Обратите внимание, что TLE означает превышение лимита времени. Это не означает, что ваш код в конечном итоге не выдаст правильный результат, но он не дошел до этой точки за отведенное время. Другими словами, выбранный вами алгоритм недостаточно эффективен. Ваш обход в глубину посетит все возможные пути от исходной ячейки по доске. Это быстро приведет к миллионам и миллиардам путей, уже для относительно небольших 𝑛.

Улучшения

Обход в ширину значительно улучшит эту ситуацию, поскольку здесь не имеет значения, насколько велика доска: если существует кратчайший путь длиной 𝑘, то BFS никогда не будет просматривать пути, длина которых превышает 𝑘.

Еще одним улучшением может быть использование алгоритма A*: этот обход может отдавать предпочтение путям, идущим в направлении цели, что позволяет быстрее найти ее.

Но наиболее эффективно наблюдать, что когда два поля находятся далеко друг от друга, существует математическая формула, которая может дать вам количество ходов. И вы можете отдельно рассматривать случаи, когда два поля расположены близко и когда они могут быть ограничены границами небольшой доски.

Определить формулу и все граничные случаи немного утомительно, но это хорошее упражнение.

Вот реализация:

int countMoves(int n, int ax, int ay, int bx, int by) {
    // Mirror in order to get A in the first quadrant of the board
    if (ax > n - 1 - ax) return countMoves(n, n - 1 - ax, ay, n - 1 - bx, by); 
    if (ay > n - 1 - ay) return countMoves(n, ax, n - 1 - ay, bx, n - 1 - by); 
    // Swap cells so A has the least X coordinate
    if (ax > bx) return countMoves(n, bx, by, ax, ay); 
    int dx = bx - ax;
    int dy = abs(ay - by);
    // Mirror along diagonal to get that dx <= dy
    if (dx > dy) return countMoves(n, ay, ax, by, bx);
    int taxi = dx + dy;
    int odd = taxi % 2;
    // Identify different cases (like small boards and nearby cells):
    return taxi == 0 ? 0 // Trivial case
           // The center of a 3x3 board and All cells on a smaller board are isolated
         : n < 3 || n == 3 && ((ax & ay) == 1 || (bx & by) == 1) ? -1
           // An adjacent cell is reached in 3 steps
         : taxi == 1 ? 3
           // Distance 4: The two ends of the center column on 3x3; (0, 0)→(1, 1); and case on same diagonal:
         : n == 3 && dx == 0 && ax == 1 || dx == dy && dx < 3 && ((ax | ay) == 0 || dx == 2) ? 4
           // The two ends of the left column on 4x4 have distance 5:
         : n == 4 && (ax | bx) == 0 && dy == 3 ? 5
           // The two general cases:
         : dy < 2 * dx ? ((taxi + 4 - 3*odd) / 6) * 2 + odd
                       : ((  dy + 3 - 2*odd) / 4) * 2 + odd;
}

int minMovesRequired(int n, Cell start, Cell end) {
    return countMoves(n, start.x - 1, start.y - 1, end.x - 1, end.y - 1);
}

Другие вопросы по теме

Небольшой хак для ggplot — простой способ добавить текст с реальными средними значениями и стандартным отклонением при использовании линий или столбцов
Получите наиболее оптимальную комбинацию мест из списка мест с помощью алгоритма графа
Один источник — кратчайший путь с одним пунктом назначения (DFS + DP) — временная сложность?
Почему BFS работает намного быстрее, чем DFS, когда я реализую их оба?
Алгоритм линейного времени для вычисления радиуса гиперсферы принадлежности
Как заменить NULL в фрейме данных на 0?
Путешествуйте из города 1 в город n, посетив не менее 3 нечетных городов
Как я могу создать трехмерную гистограмму и построить ее в Excel, используя данные, где отрицательные значения на графике также будут окрашены?
Как правильно провести границу между записями с помощью Graphviz и Haskell
Метод DriveItem Patch с ошибкой в ​​Graph Api