题目描述
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
解题思路
使用深度优先搜索(Depth First Search,DFS)方法进行求解。回溯是深度优先搜索的一种特例,它在一次搜索过程中需要设置一些本次搜索过程的局部状态,并在本次搜索结束之后清除状态。而普通的深度优先搜索并不需要使用这些局部状态,虽然还是有可能设置一些全局状态。
递归DFS
class Solution {
public:
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0}, sum = 1;
int movingCount(int threshold, int rows, int cols) {
if(threshold<=0 || rows<=0 || cols<=0) return 0;
vector<bool> visited(rows*cols, false);
DFS(0, 0, threshold, rows, cols, visited);
return sum;
}
void DFS(int x, int y, int k, int m, int n, vector<bool> &v) {
v[x*n+y] = true;
for(int d=0; d<4; ++d) {
int nx = x+dx[d], ny = y+dy[d];
if((nx>=0 && nx<m) && (ny>=0 && ny<n) && (!v[nx*n+ny])
&& (nx%10+nx/10+ny%10+ny/10 <=k)) {
++sum;
DFS(nx, ny, k, m, n, v);
}
}
}
};
循环DFS
class Solution {
public:
int movingCount(int threshold, int rows, int cols) {
if(threshold<=0 || rows<=0 || cols<=0) return 0;
stack<int> s;
vector<bool> visited(rows*cols, false);
int xoy[2][4] = {{0, 1, 0, -1}, {1, 0, -1, 0}}, count = 0;
s.push(0);
visited[0] = true;
while(!s.empty()) {
int cur = s.top(); s.pop();
count++;
for(int d=0; d<4; ++d) {
int x = cur/cols+xoy[0][d], y = cur%cols+xoy[1][d], nex = x*cols+y;
if((x>=0 && x<rows) && (y>=0 && y<cols) && !visited[nex]
&& (x%10+x/10+y%10+y/10 <= threshold)) {
s.push(nex);
visited[nex] = true;
}
}
}
return count;
}
};
由于是遍历寻找所有可以到达的地方,所以无所谓先后顺序,也可用广度优先搜索(BFS)
循环BFS
class Solution {
public:
int movingCount(int threshold, int rows, int cols) {
if(threshold<=0 || rows<=0 || cols<=0) return 0;
queue<int> q;
vector<bool> v(rows*cols, false);
int xoy[2][4] = {{0,1,0,-1}, {1,0,-1,0}}, count = 0;
q.push(0);
v[0] = true;
while(!q.empty()) {
int cur = q.front(); q.pop();
++count;
for(int d=0; d<4; ++d) {
int x = cur/cols+xoy[0][d], y = cur%cols+xoy[1][d], nex = x*cols+y;
if((x>=0 && x<rows) && (y>=0 && y<cols) && !v[nex]
&& (x%10+x/10+y%10+y/10 <= threshold)) {
q.push(nex);
v[nex] = true;
}
}
}
return count;
}
};