#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 Position { int i; int j; Position(int i, int j) { this->i = i; this->j = j; } bool operator==(const Position &rhs) const { return (i == rhs.i && j == rhs.j); // || (j == rhs.i && i == rhs.j); } bool operator<(const Position &rhs) const { return (i < rhs.i) || (i <= rhs.i && j < rhs.j); // || (i <= rhs.j && j < rhs.i); } }; std::ostream& operator<< (std::ostream& stream, const Position &position) { stream << "(i: " << position.i << " j: " << position.j << ")"; return stream; } class KnightL { private: int a_; int b_; int boardSize_; public: KnightL(int a, int b, int boardSize) : a_(a), b_(b), boardSize_(boardSize) { } private: void addIfValid(std::set &positions, const Position &position, int incrementI, int incrementJ) { Position newPosition = Position(position.i + incrementI, position.j + incrementJ); if(newPosition.i >= 0 && newPosition.j >= 0 && newPosition.i <= boardSize_ - 1 && newPosition.j <= boardSize_ - 1) { //std::cout << "Adding " << newPosition << std::endl; positions.insert(newPosition); } else { //std::cout << "No " << newPosition << std::endl; } } void addNextPositionsForCurrentPosition(Position currentPosition, std::set &positions) { // TODO: Remove the half of these that are duplicative. addIfValid(positions, currentPosition, a_, b_); addIfValid(positions, currentPosition, -a_, b_); addIfValid(positions, currentPosition, a_, -b_); addIfValid(positions, currentPosition, -a_, -b_); addIfValid(positions, currentPosition, b_, a_); addIfValid(positions, currentPosition, -b_, a_); addIfValid(positions, currentPosition, b_, -a_); addIfValid(positions, currentPosition, -b_, -a_); } public: int findIterations() { std::set currentIterationPositions; // Starting position currentIterationPositions.insert(Position(0,0)); // Ending position const Position endingPosition = Position(boardSize_ - 1, boardSize_ - 1); for(int iteration = 0; iteration < boardSize_ * boardSize_; iteration++) { std::set nextIterationPositions; for (std::set::iterator positionsIter = currentIterationPositions.begin(); positionsIter != currentIterationPositions.end(); positionsIter++) { // std::cout << "addNextPositionsForCurrentPosition " << *positionsIter << std::endl; if (endingPosition == *positionsIter) { //std::cout << "Found End Positions!!!!! - " << iteration << std::endl; return iteration; } addNextPositionsForCurrentPosition(*positionsIter, nextIterationPositions); } //for(Position p : nextIterationPositions) { // std::cout << p << " "; //} //std::cout << std::endl; currentIterationPositions = nextIterationPositions; } // Didn't find the end position return -1; } }; int main(){ int n; cin >> n; int output[n][n]; // TODO: Optimize for only doing half of the graph. for (int a = 1; a < n; a++) { for (int b = 1; b < n; b++) { KnightL knightL = KnightL(a, b, n); output[a][b] = knightL.findIterations(); } } for (int a = 1; a < n; a++) { for (int b = 1; b < n; b++) { cout << output[a][b]; if(b < n) { std::cout << " "; } } cout << std::endl; } return 0; }