Featured image of post Number of Unique Paths

Number of Unique Paths

不同路径数

给定一个 n × m 的二维矩阵,其中的每个元素都是一个 [1,9] 之间的正整数

从矩阵中的任意位置出发,每次可以沿上下左右四个方向前进一步,走过的位置可以重复走

走了 k 次后,经过的元素会构成一个 k + 1 位数。

请求出一共可以走出多少个不同的 k + 1 位数。

输入格式

第一行包含三个整数 n, m, k

接下来 n 行,每行包含 m 个空格隔开的整数,表示给定矩阵

输出格式

输出一个整数,表示可以走出的不同 k+1 位数的个数

数据范围

对于 30% 的数据, 1 ≤ n, m ≤ 2, 0 ≤ k ≤ 2 对于 100% 的数据,1 ≤ n, m ≤ 5, 0 ≤ k ≤ 5, m × n > 1

输入样例

1
2
3
4
3 3 2
1 1 1
1 1 1
2 1 1

输出样例

1
5

分析

  1. 遍历起点:矩阵中每个 (i, j) 坐标都可以作为起点,进行搜索
  2. 深度优先搜索进行数的构造:
    • 递归地沿上下左右 4 个方向移动。
    • k 步后,将生成的 k + 1 位数存入 unordered_set,去重后计算数量
    • 递归参数包括当前位置 (x, y)、已走步数 u、当前构造的数字 cur
  3. 输出不同数的总个数

时间复杂度

每个格子最多 4^k 次递归调用,整体复杂度 O(nm * 4^k)

空间复杂度

空间复杂度为 O(1)

C++代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <unordered_set>

const int N = 10;
int g[N][N];  // 存储输入矩阵
std::unordered_set<int> s;  // 记录不同的 k + 1 位数
int n, m, k;

int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};  // 方向数组,表示四个方向的移动

// 深度优先搜索 (DFS)
void dfs(int x, int y, int u, int cur)
{
    if (u == k)  // 走 k 步后,存入 set
        s.insert(cur);
    else
    {
        for (int i = 0; i < 4; ++i)  // 遍历四个方向
        {
            int a = x + dx[i], b = y + dy[i];
            if (a >= 0 && a < n && b >= 0 && b < m)  // 确保不越界
                dfs(a, b, u + 1, cur * 10 + g[a][b]);  // 递归搜索
        }
    }
}

int main()
{
    scanf("%d%d%d", &n, &m, &k);  // 读取 n, m, k
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
            scanf("%d", &g[i][j]);  // 读取矩阵数据

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
            dfs(i, j, 0, g[i][j]);  // 每个点作为起点进行 DFS

    printf("%d\n", s.size());  // 输出不同的 k + 1 位数个数
    return 0;
}
ALL RIGHTS RESERVED.
Built with Hugo
Theme Stack designed by Jimmy