题目
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
代码和解释
看到这道题目之后,我首先想的是,分解横坐标和纵坐标,对整个二维数组的每一个位置都采用这个方法,然后计算出有多少个点满足条件,但是又想,不对啊,这样的话,万一有个点虽然满足小于阈值,但是如果它不可到达的话,就不好办了。想到这里,我想着或许数学会证明不会出现这种情况,但是我吧,就难得想了,直接看了答案。答案大多用的是DFS和BFS.好吧,我完全没想到这两种方法。。
DFS解题
DFS简单来说,应用到这道题目,看到方法,也是可以理解的,应该是可以解这道题目。但是,我随之遇到了一个很大的问题,就是题目中说到的“上 下 左 右”的方向去运动。这在代码中该如何表达出来,我貌似一直没有在代码中遇到过这种类型的东西。我就去研究了下,别人的代码。原来是用一个数组实现的。
int dir[5]={-1,0,1,0,-1};
这个数组结合这个循环的话,就可以实现对四个方向都遍历一遍。真的是很奇妙啊!
for(int i=0;i<4;i++){
dfs(x+dir[i],y+dir[i+1],threshold,r,c,ret,b);
}
剩下的部分,就是按照DFS的套路来写的了。
class Solution {
public:
int dir[5]={-1,0,1,0,-1};
int check(int n){
int sum=0;
while(n){
sum+=(n%10);
n=n/10;
}
return sum;
}
void dfs(int x,int y,int threshold,int r,int c, int &ret,int **b){
if(x<0||x>=r||y<0||y>=c||b[x][y]==1){
return;
}
if(check(x)+check(y)>threshold){
return;
}
b[x][y]=1;
ret+=1;
for(int i=0;i<4;i++){
dfs(x+dir[i],y+dir[i+1],threshold,r,c,ret,b);
}
}
int movingCount(int threshold, int rows, int cols)
{
if(threshold<0){
return 0;
}
int ret=0;
int **mask = new int*[rows];
for (int i = 0; i < rows; i++)
{
mask[i] = new int[cols];
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
mask[i][j] = 0;
}
}
dfs(0,0,threshold,rows,cols,ret,mask);
for (int i = 0; i < rows; i++)
{
delete[] mask[i];
}
delete[] mask;
return ret;
}
};
BFS解题
BFS的话就是使用队列来做这件事。表达“左 右 上 下”的方法是一样的。
class Solution {
public:
using coordinate = pair<int,int>;
int dir[5] = {-1, 0, 1, 0, -1};
int check(int n) {
int sum = 0;
while (n) {
sum += (n % 10);
n /= 10;
}
return sum;
}
int movingCount(int sho, int rows, int cols)
{
if (sho <= 0) {
return 0;
}
int ret = 0;
int mark[rows][cols];
memset(mark, -1, sizeof(mark));
queue<coordinate> q;
q.push({0, 0});
mark[0][0] = 1;
while (!q.empty()) {
auto node = q.front();
q.pop();
// 每次保证进队列的都是满足条件的坐标
++ret;
for (int i = 0; i < 4; ++i) {
int x = node.first + dir[i];
int y = node.second + dir[i + 1];
if (x >= 0 && x < rows && y >= 0 && y < cols && mark[x][y] == -1) {
if (check(x) + check(y) <= sho) {
q.push({x, y});
mark[x][y] = 1;
}
}
}
}
return ret;
}
};