📜  门| GATE 2017 MOCK II |问题 4(1)

📅  最后修改于: 2023-12-03 14:58:17.906000             🧑  作者: Mango

门 | GATE 2017 MOCK II | 问题 4

这道题目出自 GATE 2017 MOCK II 的练习题目,是一道关于递归和指针的考察题目。

题目描述

在这道题目中,我们需要完成一个名为 count_paths() 的函数,在该函数中,需计算出从给定的起点到终点的所有可能路径,并返回这些路径数量。

这道题目给定的输入信息会包含一个 $n\times n$ 的矩阵,矩阵中包含的是01,其中 1 表示可以行走的区域,而 0 表示不可行走的区域。

通过输入矩阵的行数、列数、起点和终点的坐标,让我们来统计能够从起点到达终点的路径数量。

示例输入输出
示例输入

输入的第一行会有一个正整数 $t$,表示测试用例数量。

对于每个测试用例,第一行包含两个正整数 $n$ 和 $m$,表示矩阵的行数和列数。

接下来的 $n$ 行,每行包含 $m$ 个 01,表示该点可否行走。

接下来一行两个正整数 $sx$ 和 $sy$,表示起点的坐标(第 $sx$ 行,第 $sy$ 列)。

接下来一行两个正整数 $tx$ 和 $ty$,表示终点的坐标(第 $tx$ 行,第 $ty$ 列)。

接下来紧跟着 $T$ 行查询,每行两个正整数 $x$ 和 $y$,表示查询从该点(第 $x$ 行,第 $y$ 列)出发到终点的路径数量。

示例输出

对于每个查询,输出一行表示从该点出发到终点的路径数量。

解题思路

这道题目主要考察的是递归的思想和指针的使用。具体思路如下:

  1. 定义一个 count_paths() 函数来统计能够从起点到达终点的路径数量。

  2. 对于某一个格子(i, j),我们需要判断其是否可行走。如果该格子是不可行走的,则直接返回0。

  3. 如果该格子本身就是终点,则返回1。

  4. 否则,我们需要依次检查格子的上、下、左、右四个方向是否可行走。如果可行走,则从该格子的邻居出发,寻找到终点的所有可能路径,然后累加起来即可。如果邻居格子中的路径数目有更新,则将本格子的路径数目与之累加,表示从本格子出发可以到达的路径数目。

  5. 利用指针的方式避免对 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);
}

需要注意的是,不同的编译器可能对变量名的作用域有不同的限制,本文中定义的变量作用于请谨慎参考。

总结

以上就是这道关于递归和指针的题目的详细解析。这道题目中的递推公式比较简单,但是需要注意的实现细节比较多,所以需要仔细掌握。