【问题标题】:Shortest path for robot moving on a grid机器人在网格上移动的最短路径
【发布时间】:2021-03-11 15:25:49
【问题描述】:

我的作业有问题。我写了一个代码,但它在某些输入上给出了错误的答案(我看不到输入)。但是,该代码适用于我尝试的所有示例。

这就是问题所在。

机器人将邮件投递到 X 的各个角落。X 国可以表示为一个 N × M 字段,其中每个单元格要么可交叉(表示为“.”)或不可交叉(“#”)。 从当前单元格开始,机器人只能移动到相邻单元格。机器人也需要转弯,例如,如果机器人向右走,并且需要向上移动,他首先向左转弯。同样,它可以向右转。机器人的开发人员还提供了与当前方向相反的方向转弯。计算最短路径时没有考虑转弯,因为机器人很容易做到这一点。 由于故障,机器人在左转后不能再左转,直到右转,反之亦然。转身是独立进行的,不会影响此规则,但是,机器人在同一个单元格中不能转超过一圈。你被指派为机器人编写一个修改过的程序,以便它可以计算出现此故障的最短路径。

输入示例:

5 5 // N and M
#...# // grid
..#.#
..#.#
..#.#
#....
2 2 // source
2 4 // destination

输出应包含最短路径的长度和最短路径本身(如果没有最短路径,则为“-1”)。保证源和目标是可以通过的。您可以在第一步之前将机器人转向任何方向。

这就是我所做的。我为每个单元格计算了具有 12 个节点的图形(一个用于方向(上/下/左/右)和可用移动(左/右/两者)的每种组合)。使用堆栈实现 BFS(最初堆栈中有 2 个顶点,一个用于源(上 + 两者),一个用于(左 + 两者))。如果 BFS 到达与目的地对应的 12 个节点之一,则 BFS 停止。

我的代码:

#include <algorithm>
#include <iostream>
#include <vector>
#include <list>
#include <utility>


class Graph {
public:
    std::vector<std::vector<int>> adjacent_;
    int number_of_vertices_;
    explicit Graph(int number_of_vertices);

    void AddEdge(int first_vertex, int second_vertex) {
        adjacent_[first_vertex].emplace_back(second_vertex);
    }
};


Graph::Graph(int number_of_vertices) {
    number_of_vertices_ = number_of_vertices;

    std::vector<std::vector<int>> adjacent(number_of_vertices);
    adjacent_ = adjacent;
}


enum Looks { UP = 0, DOWN = 3, LEFT = 6, RIGHT = 9 };


enum Moves { L = 0, R = 1, LR = 2 };


void MovesRight(int row, int column, int number_of_columns, Graph &map) {
    int rows_in_map = 12 * row;

    map.AddEdge((rows_in_map + UP + R) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + UP + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column + 1);

    map.AddEdge((rows_in_map + RIGHT + R) * number_of_columns + column,
                (rows_in_map + RIGHT + R) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + RIGHT + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + LR) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + RIGHT + L) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column + 1);

    map.AddEdge((rows_in_map + LEFT + R) * number_of_columns + column,
                (rows_in_map + RIGHT + R) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + LEFT + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + LR) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + LEFT + L) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column + 1);

    map.AddEdge((rows_in_map + DOWN + L) * number_of_columns + column,
                (rows_in_map + RIGHT + R) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + DOWN + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + R) * number_of_columns + column + 1);
}


void MovesLeft(int row, int column, int number_of_columns, Graph &map) {
    int rows_in_map = 12 * row;

    map.AddEdge((rows_in_map + UP + L) * number_of_columns + column,
                (rows_in_map + LEFT + R) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + UP + LR) * number_of_columns + column,
                (rows_in_map + LEFT + R) * number_of_columns + column - 1);

    map.AddEdge((rows_in_map + RIGHT + R) * number_of_columns + column,
                (rows_in_map + LEFT + R) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + RIGHT + LR) * number_of_columns + column,
                (rows_in_map + LEFT + LR) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + RIGHT + L) * number_of_columns + column,
                (rows_in_map + LEFT + L) * number_of_columns + column - 1);

    map.AddEdge((rows_in_map + LEFT + R) * number_of_columns + column,
                (rows_in_map + LEFT + R) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + LEFT + LR) * number_of_columns + column,
                (rows_in_map + LEFT + LR) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + LEFT + L) * number_of_columns + column,
                (rows_in_map + LEFT + L) * number_of_columns + column - 1);

    map.AddEdge((rows_in_map + DOWN + R) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + DOWN + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column - 1);
}


void MovesUp(int row, int column, int number_of_columns, Graph &map) {
    int rows_in_map = 12 * row;

    map.AddEdge((rows_in_map + UP + L) * number_of_columns + column,
                (rows_in_map - 12 + UP + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + UP + LR) * number_of_columns + column,
                (rows_in_map - 12 + UP + LR) * number_of_columns + column);
    map.AddEdge((rows_in_map + UP + R) * number_of_columns + column,
                (rows_in_map - 12 + UP + R) * number_of_columns + column);

    map.AddEdge((rows_in_map + RIGHT + L) * number_of_columns + column,
                (rows_in_map - 12 + UP + R) * number_of_columns + column);
    map.AddEdge((rows_in_map + RIGHT + LR) * number_of_columns + column,
                (rows_in_map - 12 + UP + R) * number_of_columns + column);

    map.AddEdge((rows_in_map + LEFT + R) * number_of_columns + column,
                (rows_in_map - 12 + UP + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + LEFT + LR) * number_of_columns + column,
                (rows_in_map - 12 + UP + L) * number_of_columns + column);

    map.AddEdge((rows_in_map + DOWN + L) * number_of_columns + column,
                (rows_in_map - 12 + UP + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + DOWN + LR) * number_of_columns + column,
                (rows_in_map - 12 + UP + LR) * number_of_columns + column);
    map.AddEdge((rows_in_map + DOWN + R) * number_of_columns + column,
                (rows_in_map - 12 + UP + R) * number_of_columns + column);
}


void MovesDown(int row, int column, int number_of_columns, Graph &map) {
    int rows_in_map = 12 * row;

    map.AddEdge((rows_in_map + UP + L) * number_of_columns + column,
                (rows_in_map  + 12 + DOWN + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + UP + LR) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + LR) * number_of_columns + column);
    map.AddEdge((rows_in_map + UP + R) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + R) * number_of_columns + column);

    map.AddEdge((rows_in_map + RIGHT + R) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + RIGHT + LR) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + L) * number_of_columns + column);

    map.AddEdge((rows_in_map + LEFT + L) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + R) * number_of_columns + column);
    map.AddEdge((rows_in_map + LEFT + LR) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + R) * number_of_columns + column);

    map.AddEdge((rows_in_map + DOWN + L) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + DOWN + LR) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + LR) * number_of_columns + column);
    map.AddEdge((rows_in_map + DOWN + R) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + R) * number_of_columns + column);
}


void MakeGraph(int number_of_rows, int number_of_columns,
               std::vector<std::vector<char>> &grid, Graph &map) {

    for (int row = 0; row < number_of_rows; ++row) {
        for (int column = 0; column < number_of_columns; ++column) {
            std::cin >> grid[row][column];
        }
    }

    for (int row = 0; row < number_of_rows; ++row) {
        for (int column = 0; column < number_of_columns; ++column) {
            if (column + 1 < number_of_columns) {
                if (grid[row][column] == '.' && grid[row][column + 1] == '.') {
                    MovesRight(row, column, number_of_columns, map);
                }
            }
            if (0 < column) {
                if (grid[row][column] == '.' && grid[row][column - 1] == '.') {
                    MovesLeft(row, column, number_of_columns, map);
                }
            }
            if (0 < row) {
                if (grid[row][column] == '.' && grid[row - 1][column] == '.') {
                    MovesUp(row, column, number_of_columns, map);
                }
            }
            if (row + 1 < number_of_rows) {
                if (grid[row][column] == '.' && grid[row + 1][column] == '.') {
                    MovesDown(row, column, number_of_columns, map);
                }
            }
        }
    }
}


int BFS(Graph &map, int source, int destination,
         std::vector<int> &predecessor, std::vector<int> &distance,
        int number_of_columns) {

    std::list<int> queue;

    std::vector<bool> visited(map.number_of_vertices_, false);

    visited[source + (UP + LR) * number_of_columns] = true;
    distance[source + (UP + LR) * number_of_columns] = 0;
    queue.push_back(source + (UP + LR) * number_of_columns);
    visited[source + (LEFT + LR) * number_of_columns] = true;
    distance[source + (LEFT + LR) * number_of_columns] = 0;
    queue.push_back(source + (LEFT + LR) * number_of_columns);

    while (!queue.empty()) {
        int vertex;
        vertex = queue.front();
        queue.pop_front();


        for (size_t counter = 0; counter < map.adjacent_[vertex].size(); ++counter) {
            int current_vertex = map.adjacent_[vertex][counter];
            if (!visited[current_vertex]) {
                visited[current_vertex] = true;
                distance[current_vertex] = distance[vertex] + 1;
                predecessor[current_vertex] = vertex;
                queue.push_back(current_vertex);

                if ((current_vertex / (12 * number_of_columns)) * (12 * number_of_columns)
                    + (current_vertex % number_of_columns) == destination) {
                    return current_vertex;
                }
            }
        }
    }

    return -1;
}


void printShortestDistance(Graph &map, int source,
                           int destination, int number_of_columns) {

    std::vector<int> predecessor(map.number_of_vertices_, -1);
    std::vector<int> distance(map.number_of_vertices_, 10000000);


    int result = BFS(map, source, destination, predecessor, distance,
        number_of_columns);

    if (result == -1) {
        std::cout << -1 << "\n";
    } else {
        std::cout << distance[result] << "\n";
        int current_vertex = result;
        std::vector<std::pair<int, int>> path;

        while (current_vertex != -1) {
            path.emplace_back(((current_vertex / number_of_columns) / 12) + 1,
                              (current_vertex % number_of_columns) + 1);
            current_vertex = predecessor[current_vertex];
        }
        for (size_t i = 0; i < path.size(); ++i) {
            std::cout << path[path.size() - 1 - i].first << " "<<
            path[path.size() - 1 - i].second << "\n";
        }
    }
}


int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int number_of_rows, number_of_columns;
    std::cin >> number_of_rows >> number_of_columns;

    std::vector<std::vector<char>> grid(number_of_rows,
                                        std::vector<char>(number_of_columns));
    Graph map(12 * number_of_rows * number_of_columns);

    MakeGraph(number_of_rows, number_of_columns, grid, map);

    int first_row, second_row, first_column, second_column;
    std::cin >> first_row >> first_column >> second_row >> second_column;
    --first_row;
    --first_column;
    --second_row;
    --second_column;

    int source = 12 * first_row * number_of_columns + first_column;
    int destination = 12 * second_row * number_of_columns + second_column;

    printShortestDistance(map, source, destination, number_of_columns);



    return 0;
}

您能否告诉我在我的实现中出了什么问题,或者就哪些输入可能会失败提供一些想法?

【问题讨论】:

  • 你尝试过更复杂的测试用例吗?像源 = 1 3 和目的地 5 5 还是其他地图?
  • @Surt 是的,当然,我尝试了多个不同的地图,但找不到一个给出错误答案的地图。我想我不擅长制作迷宫。
  • 在您的 BFS 中,您将两个顶点添加到队列中,如何以及为什么选择它们?
  • @Surf 机器人朝上的第一个顶点可以左右转向,机器人朝左的第二个顶点可以左右转向。这是因为机器人最初可以面向任何方向(其他两个方向仍然考虑,因为机器人可以转身)。

标签: c++ algorithm breadth-first-search shortest-path


【解决方案1】:

此地图在x 失败,更精简的地图可能更易于查看。来源在上,左,目的地在下,右。

Seed: 3499211612
...#..
#..#.#
..##.#
.#..#.
x.....
#..#..

***...
.**...
**....
*.....
*.....
......

这些节点有一个将它们视为前驱的节点(由于您的图表,一些可能会被访问​​更多次。

用于测试的代码

#include <algorithm>
#include <iostream>
#include <vector>
#include <list>
#include <utility>

using GridType = std::vector<std::vector<char>>;
constexpr char empty { '.' };
constexpr char block { '#' };

class Graph {
public:
    std::vector<std::vector<int>> adjacent_;
    int number_of_vertices_;
    explicit Graph(int number_of_vertices);

    void AddEdge(int first_vertex, int second_vertex) {
        adjacent_[first_vertex].emplace_back(second_vertex);
    }
};


Graph::Graph(int number_of_vertices) {
    number_of_vertices_ = number_of_vertices;

    std::vector<std::vector<int>> adjacent(number_of_vertices);
    adjacent_ = adjacent;
}


enum Looks { UP = 0, DOWN = 3, LEFT = 6, RIGHT = 9 };


enum Moves { L = 0, R = 1, LR = 2 };


void MovesRight(int row, int column, int number_of_columns, Graph &map) {
    int rows_in_map = 12 * row;

    map.AddEdge((rows_in_map + UP + R) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + UP + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column + 1);

    map.AddEdge((rows_in_map + RIGHT + R) * number_of_columns + column,
                (rows_in_map + RIGHT + R) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + RIGHT + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + LR) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + RIGHT + L) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column + 1);

    map.AddEdge((rows_in_map + LEFT + R) * number_of_columns + column,
                (rows_in_map + RIGHT + R) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + LEFT + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + LR) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + LEFT + L) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column + 1);

    map.AddEdge((rows_in_map + DOWN + L) * number_of_columns + column,
                (rows_in_map + RIGHT + R) * number_of_columns + column + 1);
    map.AddEdge((rows_in_map + DOWN + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + R) * number_of_columns + column + 1);
}


void MovesLeft(int row, int column, int number_of_columns, Graph &map) {
    int rows_in_map = 12 * row;

    map.AddEdge((rows_in_map + UP + L) * number_of_columns + column,
                (rows_in_map + LEFT + R) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + UP + LR) * number_of_columns + column,
                (rows_in_map + LEFT + R) * number_of_columns + column - 1);

    map.AddEdge((rows_in_map + RIGHT + R) * number_of_columns + column,
                (rows_in_map + LEFT + R) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + RIGHT + LR) * number_of_columns + column,
                (rows_in_map + LEFT + LR) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + RIGHT + L) * number_of_columns + column,
                (rows_in_map + LEFT + L) * number_of_columns + column - 1);

    map.AddEdge((rows_in_map + LEFT + R) * number_of_columns + column,
                (rows_in_map + LEFT + R) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + LEFT + LR) * number_of_columns + column,
                (rows_in_map + LEFT + LR) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + LEFT + L) * number_of_columns + column,
                (rows_in_map + LEFT + L) * number_of_columns + column - 1);

    map.AddEdge((rows_in_map + DOWN + R) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column - 1);
    map.AddEdge((rows_in_map + DOWN + LR) * number_of_columns + column,
                (rows_in_map + RIGHT + L) * number_of_columns + column - 1);
}


void MovesUp(int row, int column, int number_of_columns, Graph &map) {
    int rows_in_map = 12 * row;

    map.AddEdge((rows_in_map + UP + L) * number_of_columns + column,
                (rows_in_map - 12 + UP + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + UP + LR) * number_of_columns + column,
                (rows_in_map - 12 + UP + LR) * number_of_columns + column);
    map.AddEdge((rows_in_map + UP + R) * number_of_columns + column,
                (rows_in_map - 12 + UP + R) * number_of_columns + column);

    map.AddEdge((rows_in_map + RIGHT + L) * number_of_columns + column,
                (rows_in_map - 12 + UP + R) * number_of_columns + column);
    map.AddEdge((rows_in_map + RIGHT + LR) * number_of_columns + column,
                (rows_in_map - 12 + UP + R) * number_of_columns + column);

    map.AddEdge((rows_in_map + LEFT + R) * number_of_columns + column,
                (rows_in_map - 12 + UP + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + LEFT + LR) * number_of_columns + column,
                (rows_in_map - 12 + UP + L) * number_of_columns + column);

    map.AddEdge((rows_in_map + DOWN + L) * number_of_columns + column,
                (rows_in_map - 12 + UP + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + DOWN + LR) * number_of_columns + column,
                (rows_in_map - 12 + UP + LR) * number_of_columns + column);
    map.AddEdge((rows_in_map + DOWN + R) * number_of_columns + column,
                (rows_in_map - 12 + UP + R) * number_of_columns + column);
}


void MovesDown(int row, int column, int number_of_columns, Graph &map) {
    int rows_in_map = 12 * row;

    map.AddEdge((rows_in_map + UP + L) * number_of_columns + column,
                (rows_in_map  + 12 + DOWN + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + UP + LR) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + LR) * number_of_columns + column);
    map.AddEdge((rows_in_map + UP + R) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + R) * number_of_columns + column);

    map.AddEdge((rows_in_map + RIGHT + R) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + RIGHT + LR) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + L) * number_of_columns + column);

    map.AddEdge((rows_in_map + LEFT + L) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + R) * number_of_columns + column);
    map.AddEdge((rows_in_map + LEFT + LR) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + R) * number_of_columns + column);

    map.AddEdge((rows_in_map + DOWN + L) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + L) * number_of_columns + column);
    map.AddEdge((rows_in_map + DOWN + LR) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + LR) * number_of_columns + column);
    map.AddEdge((rows_in_map + DOWN + R) * number_of_columns + column,
                (rows_in_map + 12 + DOWN + R) * number_of_columns + column);
}


void FillGraph(int number_of_rows, int number_of_columns,
               std::vector<std::vector<char>> &grid, Graph &map) {
  for (int row = 0; row < number_of_rows; ++row) {
      for (int column = 0; column < number_of_columns; ++column) {
          if (column + 1 < number_of_columns) {
              if (grid[row][column] == '.' && grid[row][column + 1] == '.') {
                  MovesRight(row, column, number_of_columns, map);
              }
          }
          if (0 < column) {
              if (grid[row][column] == '.' && grid[row][column - 1] == '.') {
                  MovesLeft(row, column, number_of_columns, map);
              }
          }
          if (0 < row) {
              if (grid[row][column] == '.' && grid[row - 1][column] == '.') {
                  MovesUp(row, column, number_of_columns, map);
              }
          }
          if (row + 1 < number_of_rows) {
              if (grid[row][column] == '.' && grid[row + 1][column] == '.') {
                  MovesDown(row, column, number_of_columns, map);
              }
          }
      }
  }
}

void MakeGraph(int number_of_rows, int number_of_columns,
               std::vector<std::vector<char>> &grid, Graph &map) {

    for (int row = 0; row < number_of_rows; ++row) {
        for (int column = 0; column < number_of_columns; ++column) {
            std::cin >> grid[row][column];
        }
    }

    FillGraph(number_of_rows, number_of_columns, grid, map);
}


int BFS(Graph &map, int source, int destination,
         std::vector<int> &predecessor, std::vector<int> &distance,
        int number_of_columns) {

    std::list<int> queue;

    std::vector<bool> visited(map.number_of_vertices_, false);

    visited[source + (UP + LR) * number_of_columns] = true;
    distance[source + (UP + LR) * number_of_columns] = 0;
    queue.push_back(source + (UP + LR) * number_of_columns);
    visited[source + (LEFT + LR) * number_of_columns] = true;
    distance[source + (LEFT + LR) * number_of_columns] = 0;
    queue.push_back(source + (LEFT + LR) * number_of_columns);

    int vertex = 0;
    while (!queue.empty()) {
        vertex = queue.front();
        queue.pop_front();

        for (size_t counter = 0; counter < map.adjacent_[vertex].size(); ++counter) {
            int current_vertex = map.adjacent_[vertex][counter];
            if (!visited[current_vertex]) {
                visited[current_vertex] = true;
                distance[current_vertex] = distance[vertex] + 1;
                predecessor[current_vertex] = vertex;
                queue.push_back(current_vertex);

                if ((current_vertex / (12 * number_of_columns)) * (12 * number_of_columns)
                    + (current_vertex % number_of_columns) == destination) {
                    return current_vertex;
                }
            }
        }
    }

    return -vertex;
}

void PrintGrid(std::vector<std::vector<char>>& grid) {
  for(auto& row : grid) {
    for(auto& pos : row) {
      std::cout << pos;
    }
    std::cout << '\n';
  }
}


int printShortestDistance(Graph &map, int source,
                           int destination, int number_of_columns,
                          bool showMap = false) {

    std::vector<int> predecessor(map.number_of_vertices_, -1);
    std::vector<int> distance(map.number_of_vertices_, 10000000);

    int result = BFS(map, source, destination, predecessor, distance,
        number_of_columns);

    if (showMap) {
      GridType grid(number_of_columns, std::vector<char>(number_of_columns, empty));

      for(auto pred : predecessor) {
        int row = ((pred / number_of_columns) / 12);
        int col = (pred % number_of_columns);
        grid[row][col] = '*';
      }
      PrintGrid(grid);
    }

    if (result <= 0) {
        std::cout << -1 << "\n";
    } else {
        std::cout << distance[result] << "\n";
        int current_vertex = result;
        std::vector<std::pair<int, int>> path;

        while (current_vertex != -1) {
            path.emplace_back(((current_vertex / number_of_columns) / 12) + 1,
                              (current_vertex % number_of_columns) + 1);
            current_vertex = predecessor[current_vertex];
        }
        for (size_t i = 0; i < path.size(); ++i) {
            std::cout << path[path.size() - 1 - i].first << " "<<
            path[path.size() - 1 - i].second << "\n";
        }
    }
    return result;
}


void RunGraph(int number_of_rows, int number_of_columns, int source, int destination) {
  std::vector<std::vector<char>> grid(number_of_rows,
                                      std::vector<char>(number_of_columns));
  Graph map(12 * number_of_rows * number_of_columns);

  MakeGraph(number_of_rows, number_of_columns, grid, map);

  printShortestDistance(map, source, destination, number_of_columns);
}

void Solve() {
  int number_of_rows, number_of_columns;
  std::cin >> number_of_rows >> number_of_columns;
  int first_row, second_row, first_column, second_column;
  std::cin >> first_row >> first_column >> second_row >> second_column;

  --first_row;
  --first_column;
  --second_row;
  --second_column;

  int source = 12 * first_row * number_of_columns + first_column;
  int destination = 12 * second_row * number_of_columns + second_column;

  RunGraph(number_of_rows, number_of_columns, source, destination);
}

#include<random>

void Test() {
  int number_of_rows = 10, number_of_columns = 10;
  int source = 0;
  int destination = 12 * (number_of_rows-1) * number_of_columns + (number_of_columns-1);
  std::random_device rd;  //Will be used to obtain a seed for the random number engine
  auto seed = rd();

  std::mt19937 gen(seed); //Standard mersenne_twister_engine seeded with rd()
  std::uniform_int_distribution<> distribrow(0, number_of_rows-1);
  std::uniform_int_distribution<> distribcol(0, number_of_columns-1);

  GridType grid(number_of_rows, std::vector<char>(number_of_columns, empty));

  for (int filled = 1; filled < (number_of_rows-1) * (number_of_columns -1); ++filled ) {
    int row = distribrow(gen);
    int column = distribcol(gen);
    while (grid[row][column] == block ||
           (!row && !column) || (row == (number_of_rows-1) && column == (number_of_columns-1))) {
      row = distribrow(gen);
      column = distribcol(gen);
    }
    grid[row][column] = block;

    Graph map(12 * number_of_rows * number_of_columns);

    FillGraph(number_of_rows, number_of_columns, grid, map);

    if (0 >= printShortestDistance(map, source, destination, number_of_columns)) {
      std::cout << "Seed: " << seed << '\n';
      PrintGrid(grid);
      printShortestDistance(map, source, destination, number_of_columns, true);
      std::cout << std::endl;
      grid[row][column] = empty;
    }
  }
}

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    Test();//Solve();

    return 0;
}

【讨论】:

  • 对不起,我不明白。你说的失败是什么意思?我同意机器人不能从左上角开始移动超过 x 点,但我的代码为此请求输出 -1。
  • @user123213,但它应该报告失败吗?可以左右转、上转、转下、左转继续?
  • 如果机器人从 (3, 2) 到 (3, 1),它应该左转下去。要从 (5, 1) 到 (5, 2),它也应该向左转,但在这些移动之间没有办法向右转。我看不出它如何从 (1, 1) 开始经过 (5, 1)。
  • @user123213 总是直线后退,然后再向前,然后转向任何方向?
  • 我不确定我是否明白你的意思。你说的任何方向是什么意思?左右转弯应交替进行,不受180度转弯影响。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-05
相关资源
最近更新 更多