BFS解决机器人运动范围问题
题目
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
思路
路径搜索问题,采用BFS(广度优先搜索),代码摘自牛客网的一位牛油。从起始点开始朝x,y方向搜索,不回头,将搜索过的节点保存入队列中,利用队列queue先进先出的特性,不断更新待搜索节点。对网格点进行布尔值赋值,通过加入每个网格点的布尔值是否为假来判断此结点是否未被访问,从而解决对同一结点重复访问的问题,即保证单一结点只被搜索一次。代码如下(关键部分加了注释~)
class Solution {
bool canreach(int threshold, int x, int y) {
int sum=0;
while(x>0)
{
sum+=x%10;
x/=10;
}
while(y>0)
{
sum+=y%10;
y/=10;
}
return sum<=threshold; //求各位数之和
}
public:
int movingCount(int threshold, int rows, int cols)
{
vector<vector<bool>>grid(rows);
for(auto &row:grid)
{
row.resize(cols,false); //网格初始化,全部赋值为false
}
queue<pair<int,int>>que;
if(canreach(threshold,0,0)) //确定网格是存在的,即行列非负
{
que.push(make_pair(0,0)); //将数对(0,0)放入队列que中
grid[0][0]=true; //起始点(0,0)处赋值为真
}
int cnt=0;
while(!que.empty()) //如果网格不存在,队列que就为空
{
++cnt;
int x,y;
tie(x,y)=que.front(); //将队列que的头元素与数对(x,y)连接
que.pop(); //队首出列,即已经判断过的位置出列
if(x+1<rows&&!grid[x+1][y]&&canreach(threshold,x+1,y))
{
grid[x+1][y]=true;
que.push(make_pair(x+1,y)); //朝x方向搜索,满足条件即入栈
}
if(y+1<cols&&!grid[x][y+1]&&canreach(threshold,x,y+1))
{
grid[x][y+1]=true;
que.push(make_pair(x,y+1)); //朝y方向搜索,满足条件即入栈
}
}
return cnt;
}
};