#include #include #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; // //map memo; // //string getKey(int row, int col) //{ // std::ostringstream ss; // ss << std::setw(2) << std::setfill('0') << row; // ss << std::setw(2) << std::setfill('0') << col; // return ss.str(); //} // //int MoveKnight(int n, int row, int col, int a, int b, int move) //{ // int temp = move; // // if (row >= n || col >= n || row < 0 || col < 0) // return -1; // // if (row == 0 && col == 0) // return move; // // string key = getKey(row, col); // if (memo.find(key) != memo.end()) // { // if (memo[key] < 0) // return -1; // // if (memo[key] > 0) // return move + memo[key]; // // if (memo[key] == 0) // memo[key] = -1; // // } // else // memo[key] = -1; // // // //for (int i = 1; i <= move; i++) // // cout << "\t"; // //cout << getKey(row, col) << " " << move << endl; // // // int minMove = INT_MAX; // // int ret = -1; // // // // ret = -1; ret = MoveKnight(n, row + a, col + b, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret); // ret = -1; ret = MoveKnight(n, row + a, col - b, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret); // // ret = -1; ret = MoveKnight(n, row - a, col + b, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret); // ret = -1; ret = MoveKnight(n, row - a, col - b, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret); // // ret = -1; ret = MoveKnight(n, row + b, col + a, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret); // ret = -1; ret = MoveKnight(n, row + b, col - a, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret); // // ret = -1; ret = MoveKnight(n, row - b, col + a, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret); // ret = -1; ret = MoveKnight(n, row - b, col - a, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret); // // // /* // ret = -1; // // if (ret == -1) {ret = MoveKnight(n, row - a, col - b, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret);} // if (ret == -1) {ret = MoveKnight(n, row - b, col - a, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret);} // if (ret == -1) {ret = MoveKnight(n, row - a, col + b, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret);} // if (ret == -1) {ret = MoveKnight(n, row - b, col + a, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret);} // if (ret == -1) {ret = MoveKnight(n, row + a, col - b, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret);} // if (ret == -1) {ret = MoveKnight(n, row + b, col - a, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret);} // if (ret == -1) {ret = MoveKnight(n, row + a, col + b, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret);} // if (ret == -1) {ret = MoveKnight(n, row + b, col + a, a, b, move + 1); minMove = (ret < 0) ? minMove : min(minMove, ret);} // */ // // if (minMove == INT_MAX) // { // memo[key] = 0; // return -1; // } // else // { // if ((minMove - temp)>=0) // memo[key] = minMove-temp; // // return minMove; // } //} // ////int KnightL(int n, int a, int b) ////{ //// // CLear memo //// memo.erase(memo.begin(), memo.end()); //// //// // Right Answer and Slow //// // DFS //// for (size_t row = 0; row < n; row++) //// { //// for (size_t col = 0; col < n; col++) //// { //// memo[getKey(row,col)]=MoveKnight(n, row, col, a, b, 0); //// } //// } //// return memo[getKey(n-1, n-1)]; //// //// //// BFS //// //for (size_t level = 1; level < n; level++) //// //{ //// // for (size_t row=level , col=0; row>=0, col<=level; row--, col++) //// // { //// // //cout << row << "," << col << " "; //// // memo[getKey(row, col)] = MoveKnight(n, row, col, a, b, 0); //// // } //// // //cout << endl; //// //} //// //for (size_t level = 1; level < n; level++) //// //{ //// // for (size_t row=n-1, col=level ; row>=0, col b.row) return true; else if (a.row == b.row) return (a.col > b.col); else return false; } }; int getPossibleCell(int n, int row, int col, cell & c) { if (row >= n || col >= n || row < 0 || col < 0) return -1; c = cell(row, col); return 0; } void getPossibleCells(int n, int row, int col, int a, int b, set & temp) { cell c(0,0); if (getPossibleCell(n, row + a, col + b, c) == 0) { temp.insert(c); } if (getPossibleCell(n, row + a, col - b, c) == 0) { temp.insert(c); } if (getPossibleCell(n, row - a, col + b, c) == 0) { temp.insert(c); } if (getPossibleCell(n, row - a, col - b, c) == 0) { temp.insert(c); } if (getPossibleCell(n, row + b, col + a, c) == 0) { temp.insert(c); } if (getPossibleCell(n, row + b, col - a, c) == 0) { temp.insert(c); } if (getPossibleCell(n, row - b, col + a, c) == 0) { temp.insert(c); } if (getPossibleCell(n, row - b, col - a, c) == 0) { temp.insert(c); } } int KnightL(int n, int a, int b) { set processedCells; set workingCells; // Start from the target workingCells.insert(cell(n - 1, n - 1)); int iteration = 0; while (workingCells.find(cell(0,0))== workingCells.end()) { set temp; // for each cell find all possible moves for (const auto& c : workingCells) { getPossibleCells(n, c.row, c.col, a, b, temp); } // remove already processed cells for (const auto& c : processedCells) { if (temp.find(c) != temp.end()) temp.erase(c); } // mark the working cells as processed for (const auto& c : workingCells) { processedCells.insert(c); } // clear working cells workingCells.clear(); // update the working cells with the temp workingCells = temp; // no possibility found if (workingCells.size() <= 0) { iteration = -1; break; } iteration++; } return iteration; } int main() { int n; cin >> n; //for (size_t i = 2; i <= n; i++) // cout << i << "=" << KnightL(i, 1, 1) << endl; //cout << KnightL(n, 1, 1) << endl; //time_t secondsStart; //time_t secondsEnd; //secondsStart = time(NULL); map cache; for (int a = 1; a < n; a++) { for (int b = 1; b < n; b++) { int minMove = -1; //string key; //key = getKey(b,a); if (cache.find(cell(b,a)) != cache.end()) minMove = cache[cell(b,a)]; else minMove = KnightL(n, a, b); cache[cell(a, b)] = minMove; cout << minMove << " "; } cout << endl; } //secondsEnd = time(NULL); return 0; }