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 };
复制代码

 

posted @   跳动的休止符  阅读(103)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示