#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; struct Node { Node(int x, int y) : x_(x), y_(y), parent_(nullptr), visited_(false) {} int x_; int y_; vector neighbours_; Node* parent_; bool visited_; string print() const { stringstream out; out << "(" << x_ << ", " << y_ << ")"; return out.str(); } void addNeighbour(Node* node) { neighbours_.push_back(node); } }; struct Graph { Graph(int a, int b, int n) : a_(a), b_(b), n_(n), nodes_(n * n, nullptr) { nodes_[0] = new Node(0, 0); buildGraph(nodes_[0]); } void buildGraph(Node* node); void addEdge(Node* node, int x, int y) { int index = calculateNodeIndex(x, y); if (index == -1) return; Node* newNode = nodes_[index]; if (!newNode) { newNode = new Node(x, y); } node->addNeighbour(newNode); // cout << "Added edge between " << node->print() << " and " // << newNode->print() << endl; nodes_[index] = newNode; } int calculateNodeIndex(int x, int y) { if (x >= 0 && x < n_ && y >= 0 && y < n_) { return y + (x * n_); } else { return -1; } } bool isEnd(int x, int y) const { return x == n_ - 1 & y == n_ - 1; } bool foundSolution() { return nodes_[calculateNodeIndex(n_ - 1, n_ - 1)] != nullptr; } int findMinMoves(); int a_; int b_; int n_; vector nodes_; }; void Graph::buildGraph(Node* node) { node->visited_ = true; int x = node->x_ + a_; int y = node->y_ + b_; addEdge(node, x, y); if (isEnd(x, y)) return; x = node->x_ - a_; y = node->y_ + b_; addEdge(node, x, y); if (isEnd(x, y)) return; x = node->x_ - a_; y = node->y_ - b_; addEdge(node, x, y); if (isEnd(x, y)) return; x = node->x_ + a_; y = node->y_ - b_; addEdge(node, x, y); if (isEnd(x, y)) return; // x = node->x_ + b_; y = node->y_ + a_; addEdge(node, x, y); if (isEnd(x, y)) return; x = node->x_ - b_; y = node->y_ + a_; addEdge(node, x, y); if (isEnd(x, y)) return; x = node->x_ - b_; y = node->y_ - a_; addEdge(node, x, y); if (isEnd(x, y)) return; x = node->x_ + b_; y = node->y_ - a_; addEdge(node, x, y); if (isEnd(x, y)) return; for (auto n : node->neighbours_) { if (!n->visited_) buildGraph(n); } } int Graph::findMinMoves() { for (auto n : nodes_) { if (n) n->visited_ = false; } list queue; Node* root = nodes_[0]; Node* last = nodes_[nodes_.size() - 1]; root->visited_ = true; queue.push_back(root); while (!queue.empty()) { Node* node = queue.front(); if (node == last) { int counter = 0; while (node->parent_) { node = node->parent_; ++counter; } return counter; } queue.pop_front(); for (auto n : node->neighbours_) { if (!n->visited_) { n->visited_ = true; n->parent_ = node; queue.push_back(n); } } } return -1; } int main() { int n; cin >> n; for (int i = 1; i < n; ++i) { for (int j = 1; j < n; ++j) { // cout << "Graph for i=" << i << ", j=" << j << endl; Graph graph(i, j, n); cout << graph.findMinMoves() << " "; } cout << endl; } return 0; }