一开始的误解:
以为满足数位之和<=k的地方都能到,实际上有可能是到不了的,因为不是x+y而是x的每一位和y的每一位相加!!!
思路一:dp
具体思路:由于只向右边和下边遍历,所以[i][j]的状态可以由[i-1][j]和[i][j-1]得到
dp[i][j]表示 是否可达,1表示可达0表示不可达
转移方程:dp[i][j]=dp[i][j-1]||dp[i-1][j]
边界:dp[0] = 1其他都是
class Solution {
public:
bool isgo(int i, int j, int k) {
int sum = 0;
while (i) {
sum += (i % 10);
i /= 10;
}
while (j) {
sum += (j % 10);
j /= 10;
}
return sum <= k;
}
int movingCount(int n, int m, int k) {
vector<int> dp(m);
dp[0] = 1;
int ans = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if (!isgo(i, j, k)) dp[j] = 0;
else dp[j] = dp[j] || (j - 1 >= 0 ? dp[j - 1] : 0);
if (dp[j]) ans++;
}
}
return ans;
}
};
思路二:bfs
class Solution {
public:
int ans = 0;
int flag[105][105] = {0};
int xy[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
bool isgo(int i, int j, int k) {
int sum = 0;
while (i) {
sum += (i % 10);
i /= 10;
}
while (j) {
sum += (j % 10);
j /= 10;
}
return sum <= k;
}
void bfs(int x, int y, int m, int n, int k) {
queue<pair<int, int>> q;
q.push({x, y});
flag[x][y] = 1;
while (!q.empty()) {
auto frt = q.front();
q.pop();
ans++;
int first = frt.first;
int second = frt.second;
for (int i = 0; i < 4; ++i) {
int xx = first + xy[i][0], yy = second + xy[i][1];
if (xx < 0 || xx >= m || yy < 0 || yy >= n) continue;
if (isgo(xx, yy, k) && !flag[xx][yy]) {
q.push({xx, yy});
flag[xx][yy] = 1;
}
}
}
}
int movingCount(int m, int n, int k) {
bfs(0, 0, m, n, k);
return ans;
}
};
注意:
从(0, 0)开始即可。
思路三:dfs
void dfs(int x, int y, int m, int n, int k) {
flag[x][y] = 1;
ans++;
for (int i = 0; i < 4; ++i) {
int xx = x + xy[i][0];
int yy = y + xy[i][1];
if (xx < 0 || xx >= m || yy < 0 || yy >= n) continue;
if (isgo(xx, yy, k) && !flag[xx][yy]) dfs(xx, yy, m, n, k);
}
}