📅  最后修改于: 2023-12-03 14:58:17.906000             🧑  作者: Mango
这道题目出自 GATE 2017 MOCK II 的练习题目,是一道关于递归和指针的考察题目。
在这道题目中,我们需要完成一个名为 count_paths()
的函数,在该函数中,需计算出从给定的起点到终点的所有可能路径,并返回这些路径数量。
这道题目给定的输入信息会包含一个 $n\times n$ 的矩阵,矩阵中包含的是0
和1
,其中 1
表示可以行走的区域,而 0
表示不可行走的区域。
通过输入矩阵的行数、列数、起点和终点的坐标,让我们来统计能够从起点到达终点的路径数量。
输入的第一行会有一个正整数 $t$,表示测试用例数量。
对于每个测试用例,第一行包含两个正整数 $n$ 和 $m$,表示矩阵的行数和列数。
接下来的 $n$ 行,每行包含 $m$ 个 0
或 1
,表示该点可否行走。
接下来一行两个正整数 $sx$ 和 $sy$,表示起点的坐标(第 $sx$ 行,第 $sy$ 列)。
接下来一行两个正整数 $tx$ 和 $ty$,表示终点的坐标(第 $tx$ 行,第 $ty$ 列)。
接下来紧跟着 $T$ 行查询,每行两个正整数 $x$ 和 $y$,表示查询从该点(第 $x$ 行,第 $y$ 列)出发到终点的路径数量。
对于每个查询,输出一行表示从该点出发到终点的路径数量。
这道题目主要考察的是递归的思想和指针的使用。具体思路如下:
定义一个 count_paths()
函数来统计能够从起点到达终点的路径数量。
对于某一个格子(i, j),我们需要判断其是否可行走。如果该格子是不可行走的,则直接返回0。
如果该格子本身就是终点,则返回1。
否则,我们需要依次检查格子的上、下、左、右四个方向是否可行走。如果可行走,则从该格子的邻居出发,寻找到终点的所有可能路径,然后累加起来即可。如果邻居格子中的路径数目有更新,则将本格子的路径数目与之累加,表示从本格子出发可以到达的路径数目。
利用指针的方式避免对 visited[][]
数组的重复访问。
根据上述思路,我们可以得到下面的代码实现:
#define N 1000
int mat[N][N];
int visited[N][N];
int n, m, sx, sy, tx, ty;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int dfs(int i, int j, int &res){
visited[i][j] = 1;
if(i == tx && j == ty) return 1;
for(int k=0;k<4;k++){
int nx = i + dx[k];
int ny = j + dy[k];
if(nx > n || nx < 1 || ny > m || ny < 1 || mat[nx][ny] == 0 || visited[nx][ny]) continue;
int ret = dfs(nx, ny, res);
if(ret){
res += ret;
}
}
return 0;
}
void count_paths(){
memset(visited, 0, sizeof visited);
int res = 0;
dfs(sx, sy, res);
printf("%d\n", res);
}
需要注意的是,不同的编译器可能对变量名的作用域有不同的限制,本文中定义的变量作用于请谨慎参考。
以上就是这道关于递归和指针的题目的详细解析。这道题目中的递推公式比较简单,但是需要注意的实现细节比较多,所以需要仔细掌握。