机器人的运动范围

题目描述

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

 

典型回溯法的问题

回溯法是一种深度优先搜索方法

按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

算法如下:

1、首先确定初始点,将初始点的行和列加入队列中保存

2、队列不为空,弹出队首元素

3、从队首元素往上下左右搜索,能够满足小于K,且未被搜索过,加入队列中

4、重复2、3

#pragma once
#include <queue>

namespace movingCount
{
	class Solution {
		struct row_col
		{
			int _row;
			int _col;
		};

	public:
		bool** _e;
		int _threshold;
		int _maxr;
		int _maxc;
		int _sum;
		int movingCount(int threshold, int rows, int cols)
		{
			if (rows <= 0 && cols <= 0)
			{
				return 0;
			}

			if (threshold < 0)
			{
				return 0;
			}

			// 初始化表
			_threshold = threshold;
			_e = new bool* [rows];
			_maxr = rows;
			_maxc = cols;
			for (int i = 0; i < rows; i++)
			{
				_e[i] = new bool[cols]();
				for (int j = 0; j < cols; j++)
				{
					_e[i][j] = false;
				}
			}

			std::queue<row_col> que;
			que.push(row_col{ 0,0 });
			_e[0][0] = true;
			_sum = 1;
			while (!que.empty())
			{
				row_col rc = que.front();
				que.pop();
				// 遍历上下左右
				satisfied( rc._row, rc._col - 1, que);
				satisfied( rc._row, rc._col + 1, que);
				satisfied( rc._row - 1, rc._col, que);
				satisfied( rc._row + 1, rc._col, que);

			}

			return _sum;
		}

        // 判断节点是否满足条件
		bool satisfied(int row, int col, std::queue<row_col> &que)
		{
			if (col < 0 || row < 0 || !(col < _maxc) || !(row < _maxr))
			{
				return false;
			}
			if (_e[row][col] == true)
			{
				return false;
			}

			int sum = sum_bit(row) + sum_bit(col);
			if (sum <= _threshold)
			{
				_e[row][col] = true;
				que.push(row_col{ row, col });
				_sum++;
				return true;
			}
			return false;
		}

        // 判断个位数的和
		int sum_bit(int row)
		{
			int ret = 0;
			while (row > 0)
			{
				ret += row % 10;
				row /= 10;
			}
			return ret;
		}
	};
}

test.cpp

#pragma once
#include "movingCount.h"

namespace movingCount
{
	void start_test()
	{
		Solution s;
		int r= s.movingCount(10, 1, 100);
	}
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值