目录
[2596. 检查骑士巡视方案](#2596. 检查骑士巡视方案)
2596. 检查骑士巡视方案
题目描述:
骑士在一张 n x n
的棋盘上巡视。在有效的巡视方案中,骑士会从棋盘的 左上角 出发,并且访问棋盘上的每个格子 恰好一次 。
给你一个 n x n
的整数矩阵 grid
,由范围 [0, n * n - 1]
内的不同整数组成,其中 grid[row][col]
表示单元格 (row, col)
是骑士访问的第 grid[row][col]
个单元格。骑士的行动是从下标 0 开始的。
如果 grid
表示了骑士的有效巡视方案,返回 true
;否则返回 false
。
注意,骑士行动时可以垂直移动两个格子且水平移动一个格子,或水平移动两个格子且垂直移动一个格子。下图展示了骑士从某个格子出发可能的八种行动路线。
示例 1:
输入:grid = [[0,11,16,5,20],[17,4,19,10,15],[12,1,8,21,6],[3,18,23,14,9],[24,13,2,7,22]]
输出:true
解释:grid 如上图所示,可以证明这是一个有效的巡视方案。
示例 2:
输入:grid = [[0,3,6],[5,8,1],[2,7,4]]
输出:false
解释:grid 如上图所示,考虑到骑士第 7 次行动后的位置,第 8 次行动是无效的。
提示:
n == grid.length == grid[i].length
3 <= n <= 7
0 <= grid[row][col] < n * n
grid
中的所有整数 互不相同
实现代码与解析:
bfs模拟
cpp
class Solution {
public:
bool checkValidGrid(vector<vector<int>>& grid) {
int n = grid.size(), m = grid[0].size(); // 边界范围
int curx = 0, cury = 0; // 当前位置
if (grid[0][0] != 0) return false;
// 不用找起点,这题必须是左上角起点,就算是对的,不是左上角起点也判为false
// for (int i = 0; i < n; i++)
// for (int j = 0; j < m; j++)
// if (grid[i][j] == 0) curx = i, cury = j;
int num = 1; // 当前位置的下一个数字
int target = n * m; // 目标值
// 偏移量
int dx[8] = {-2, -2, -1, -1, 1, 1, 2, 2};
int dy[8] = {1, -1, 2, -2, -2, 2, 1, -1};
while(true)
{
// cout << curx << " " << cury << endl;
int flag = 0; // 8个方向有无正确可走方向
for (int i = 0; i < 8; i++)
{
int x = curx + dx[i], y = cury + dy[i];
if (x < 0 || x >= n || y < 0 || y >= m) continue;
if (grid[x][y] == num)
{
curx = x;
cury = y;
num++;
flag = 1;
break; // 记得写
}
}
if (num == target) return true; // 整个地图走完了,返回true
// cout << "num:" <<num << endl;
if (flag == 0) return false; // 无方向可走
}
}
};
原理思路:
模拟,可走格子中没有下一个数字,且不是最后一个数字,直接返回false。若在可走方格中找到下一个数字,那么就移动到此格子中,知道走到最后一个数字。
比较简单,主要看代码注释就行。