小U的最大连续移动次数问题 | 豆包MarsCode AI刷题

143 阅读2分钟

问题描述

小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:

  1. 只能上坡或者下坡,不能走到高度相同的点。
  2. 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
  3. 每个位置只能经过一次,不能重复行走。

任务是帮助小U找到他在地图上可以移动的最大次数,即在符合所有条件的前提下,小U能走过的最大连续位置数量。

例如在以下2x2的地图中:

1 2
4 3

中庸行者可以选择移动顺序 3 -> 4 -> 1 -> 2,最大移动次数为3。


测试样例

样例1:

输入:m = 2, n = 2, a = [[1, 2], [4, 3]]
输出:3

样例2:

输入:m = 3, n = 3, a = [[10, 1, 6], [5, 9, 3], [7, 2, 4]]
输出:8

样例3:

输入:m = 4, n = 4, a = [[8, 3, 2, 1], [4, 7, 6, 5], [12, 11, 10, 9], [16, 15, 14, 13]]
输出:11

解题思路

此问题可以通过深度优先搜索(DFS)来解决。核心思想是从地图上的每一个位置出发,尝试所有可能的路径,并记录每一条路径的最大长度。由于每次移动都需要改变方向(从上坡变下坡或从下坡变上坡),因此在递归过程中需要传递当前的方向信息。

代码实现

def solution(m: int, n: int, a: list) -> int:
    max_moves = 0
    visited = set()

    def dfs(x, y, visited, direction, moves):
        nonlocal max_moves
        # 边界检查和已访问检查
        if x < 0 or x >= m or y < 0 or y >= n or (x, y) in visited:
            max_moves = max(max_moves, moves)
            return
        current_height = a[x][y]
        visited = visited | {(x, y)}  # 当前位置标记为已访问

        if direction == "up":
            # 尝试四个方向的上坡移动
            for dx, dy in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
                next_x = x + dx
                next_y = y + dy
                if 0 <= next_x < m and 0 <= next_y < n and (next_x, next_y) not in visited:
                    next_height = a[next_x][next_y]
                    if next_height > current_height:
                        dfs(next_x, next_y, visited, "down", moves + 1)
        elif direction == "down":
            # 尝试四个方向的下坡移动
            for dx, dy in [(0, 1), (1, 0), (-1, 0), (0, -1)]:
                next_x = x + dx
                next_y = y + dy
                if 0 <= next_x < m and 0 <= next_y < n and (next_x, next_y) not in visited:
                    next_height = a[next_x][next_y]
                    if next_height < current_height:
                        dfs(next_x, next_y, visited, "up", moves + 1)
        max_moves = max(max_moves, moves)
        return

    # 从每个位置开始,分别尝试向上和向下两种初始方向
    for i in range(m):
        for j in range(n):
            dfs(i, j, visited, "up", 0)
            dfs(i, j, visited, "down", 0)
    return max_moves