力扣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点钟位置开始分别模拟行和列可能的变化值dx和dy。

int dx[8]={1, 2, 2, 1, -1, -2, -2, -1};
int dy[8]={-2, -1, 1, 2, 2, 1, -1, -2};

骑士会从棋盘的 左上角 出发,并且访问棋盘上的每个格子恰好一次 。

if(grid[0][0]!=0)
	return false;

来约束骑士从左上角出发。

骑士的行动是从下标 0 开始的,用一个for循环来约束骑士顺序访问,保证每个格子只能访问一次,且下标递增。用一个bool变量flag来判断能否到达i,如果能到达flag置为true。如果本轮无法到达i,那么直接return flase,代表当前位置无法到达i。

        for(int i=1; i<len*len; i++)
        {
            bool flag = false;
			//探测是否能到达i,能到达flag置为true
            if(!flag)
                return false;
        }
        return true;

nrow为目前所处的行,ncol为目前所处的列。往八个方向进行探测,x,y记录从当前位置可能到达的位置,如果越界直接进入下一轮循环。如果能到达i,那么置flag为true,并将当前位置nrow和ncol更新为探测的x,y。

            for(int j=0; j<8; j++)
            {
                int x = ncol + dx[j];
                int y = nrow + dy[j];
                if(x<0 || x>=len || y<0 || y>=len)
                    continue;
                if((grid[x][y] == i))
                {
                    flag = true;
                    ncol = x;
                    nrow = y;
                } 
            }

完整代码如下:

class Solution {
public:
    bool checkValidGrid(vector<vector<int>>& grid) {
        int nrow=0, ncol=0, n=0;
        int dx[8]={1, 2, 2, 1, -1, -2, -2, -1}, dy[8]={-2, -1, 1, 2, 2, 1, -1, -2};
        if(grid[0][0]!=0)
            return false;
            
        int len = grid.size();

        for(int i=1; i<len*len; i++)
        {
            bool flag = false;
            for(int j=0; j<8; j++)
            {
                int x = ncol + dx[j];
                int y = nrow + dy[j];
                if(x<0 || x>=len || y<0 || y>=len)
                    continue;
                if((grid[x][y] == i))
                {
                    flag = true;
                    ncol = x;
                    nrow = y;
                } 
            }
            if(!flag)
                return false;
        }
        return true;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值