1197. 进击的骑士
1197. 进击的骑士
一个坐标可以从
-infinity
延伸到 +infinity
的 无限大的 棋盘上,你的 骑士 驻扎在坐标为 [0, 0]
的方格里。骑士的走法和中国象棋中的马相似,走 “日” 字:即先向左(或右)走 1 格,再向上(或下)走 2 格;或先向左(或右)走 2 格,再向上(或下)走 1 格。
每次移动,他都可以按图示八个方向之一前进。
返回 骑士前去征服坐标为 [x, y]
的部落所需的最小移动次数 。本题确保答案是一定存在的。
示例 1:
输入:x = 2, y = 1 输出:1 解释:[0, 0] → [2, 1]
示例 2:
输入:x = 5, y = 5 输出:4 解释:[0, 0] → [2, 1] → [4, 2] → [3, 4] → [5, 5]
提示:
-300 <= x, y <= 300
0 <= |x| + |y| <= 300
1 #include <iostream> 2 #include <unordered_map> 3 #include <vector> 4 #include <queue> 5 using namespace std; 6 7 // 骑士走的8个方向 8 constexpr int g_direction[8][2] = {{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}}; 9 // 棋盘最大边界值 10 class Solution { 11 public: 12 bool isInvalidPosition(int x, int y, int edgeX, int edgeY) { 13 if ((x >= 0 && x < edgeX) &&(y >= 0 && y < edgeY)) { 14 return true; 15 } 16 return false; 17 } 18 int minKnightMoves(int x, int y) { 19 // 考虑到四个象限内位置对称,都映射到第一象限正数处理 20 x = abs(x); 21 y = abs(y); 22 // 标记位置是否走过,这里数组定义大点 23 int m = x + 20; 24 int n = y + 20; 25 vector<vector<bool>> visited(m, vector<bool>(n, false)); 26 // 考虑到边界处理,目的坐标位置向外偏移10 27 x += 10; 28 y += 10; 29 30 queue<std::pair<int, int>> q; // pair对为(x, y) 31 // 起始位置入队列 32 q.push(make_pair(10, 10)); 33 visited[10][10] = true; 34 int step = 0; 35 while (!q.empty()) { 36 int size = q.size(); 37 while (size--) { 38 int nowX = q.front().first; 39 int nowY = q.front().second; 40 q.pop(); 41 if (nowX == x && nowY == y) { 42 return step; 43 } 44 // 向8个方向移动 45 for (int i = 0; i < 8; i++) { 46 int nextX = nowX + g_direction[i][0]; 47 int nextY = nowY + g_direction[i][1]; 48 if (isInvalidPosition(nextX, nextY, m, n) && (!visited[nextX][nextY])) { 49 q.push(make_pair(nextX, nextY)); 50 visited[nextX][nextY] = true; 51 } 52 } 53 } 54 step++; 55 } 56 return -1; 57 } 58 }; 59 60 int main() 61 { 62 Solution *test = new Solution(); 63 int x = 2; 64 int y = 112; 65 cout << test->minKnightMoves(x, y) << endl; 66 system("pause"); 67 return 0; 68 }
采用结构体保存骑士走的位置和步骤:
1 // 保存骑士走的位置和步数 2 struct Position { 3 int x; 4 int y; 5 int step; 6 }; 7 // 骑士走的8个方向 8 constexpr int g_direction[8][2] = {{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}}; 9 class Solution { 10 public: 11 bool isInvalidPosition(int x, int y, int edgeX, int edgeY) { 12 if ((x >= 0 && x < edgeX) &&(y >= 0 && y < edgeY)) { 13 return true; 14 } 15 return false; 16 } 17 int minKnightMoves(int x, int y) { 18 // 考虑到四个象限内位置对称,都映射到第一象限正数处理 19 x = abs(x); 20 y = abs(y); 21 // 标记位置是否走过,这里数组定义大点 22 int m = x + 20; 23 int n = y + 20; 24 vector<vector<bool>> visited(m, vector<bool>(n, false)); 25 // 考虑到边界处理,目的坐标位置向外偏移10 26 x += 10; 27 y += 10; 28 29 queue<Position> q; 30 Position start; 31 start.x = 10; 32 start.y = 10; 33 start.step = 0; 34 // 起始位置入队列 35 q.push(start); 36 visited[start.x][start.y] = true; 37 while (!q.empty()) { 38 Position now = q.front(); 39 q.pop(); 40 // 如果到达终点,则返回走的步数 41 if (now.x == x && now.y == y) 42 { 43 return now.step; 44 } 45 // 如果尚未到终点,则将8个方向移动一步后加入待处理队列 46 for (int i = 0; i < 8; i++) { 47 Position next; 48 next.x = now.x + g_direction[i][0]; 49 next.y = now.y + g_direction[i][1]; 50 if (!isInvalidPosition(next.x, next.y, m, n)) { 51 continue; 52 } 53 if (visited[next.x][next.y]) { 54 continue; 55 } 56 next.step = now.step + 1; 57 q.push(next); 58 visited[next.x][next.y] = true; 59 } 60 } 61 return -1; 62 } 63 };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具