[leetcode]Out of Boundary Paths
链接:https://leetcode.com/problems/out-of-boundary-paths/description/
Question
There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return it after mod 10^9 + 7.
Example 1
Input:m = 2, n = 2, N = 2, i = 0, j = 0
Output: 6
Explanation:
Example 2
Input:m = 1, n = 3, N = 3, i = 0, j = 1
Output: 12
Explanation:
Note:
- Once you move the ball out of boundary, you cannot move it back.
- The length and height of the grid is in range [1,50].
- N is in range [0,50].
Solution
class Solution {
public:
#define inf ((int)pow(10, 9)+7)
int direction[8][2] = {
{1,0},
{-1,0},
{0,-1},
{0,1}
};
// bool inMap(int x, int y, int m, int n) { return x >= 0 && x <= m+1 && y >= 0 && y <= n+1; }
bool isValid(int x, int y, int m, int n) { return x >= 1 && x <= m && y >= 1 && y <= n; }
int findPaths(int m, int n, int N, int i, int j) {
int dp[60][60][60] = {};
memset(dp, 0, sizeof(dp));
int cnt = 0;
dp[i+1][j+1][0] = 1;
for (int p = 1; p <= N; p++) {
for (int i = 0; i <= m+1; i++) {
for (int j = 0; j <= n+1; j++) {
for (int k = 0; k < 4; k++) {
int x = i+direction[k][0];
int y = j+direction[k][1];
// 关键思想是(x,y)表示的是(i,j)的上一次的位置而不是下一次的位置
if (isValid(x, y, m, n) && dp[x][y][p-1] > 0) {
// 注意这种大数的题目对于每个值最好都mod一下,防止越界
dp[x][y][p-1] %= inf;
dp[i][j][p] %= inf;
// 每次累积周围方格的路径数量
dp[i][j][p] += dp[x][y][p-1];
if (!isValid(i, j, m, n)) {
if (cnt >= inf) cnt %= inf;
cnt += dp[x][y][p-1];
}
}
}
}
}
}
return cnt%inf;
}
思路:为了方便表示,在上下左右都添加了空白区域,也就是说只有x >= 1 && x <= m && y >= 1 && y <= n这个区域才是界内。dp[i][j][p]表示当前的移动次数是在(i,j)的位置,移动了总共是p次。关键思想是(x,y)表示的是(i,j)的上一次的位置而不是下一次的位置。另外,由于是大数,因此每一次运算完都必须mod一下,否则可能会越界。