【字节青训】:小 U 的最大连续移动次数问题

95 阅读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

题目链接:小U的最大连续移动次数问题 - MarsCode

思路:

  1. 这里我们用到了 dfs 的算法,对每个点进行两次 dfs ,注意两次分别是 上坡和下坡
  2. 这里我们用到 bool 值来标记上下坡
  3. 然后对于dfs 参数及返回值需要进行一下处理,返回值:返回当前[x, y]往下走的最大步数,参数:坐标以及上下坡标记
  4. 注意:由于当前点不算走一步,所以对于最后结果我们需要 -1

代码如下:

#include <iostream>
#include <vector>
using namespace std;

int m, n;
//int path;

bool vis[1005][1005] = { false };

int dir[4][2] = {
    {-1,0},{0,-1},{1,0},{0,1}
};

int dfs(vector<vector<int>>& a, int i, int j, bool is_Up)
{
    int path = 0;
    vis[i][j] = true;
    for (int k = 0; k < 4; k++)
    {
        int x = dir[k][0] + i, y = dir[k][1] + j;
        if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y])
        {
            if ((is_Up && a[x][y] < a[i][j]) || (!is_Up && a[x][y] > a[i][j])) {
               
                path = max(path, dfs(a, x, y, !is_Up));
            }
        }
    }
    vis[i][j] = false;
    return path + 1;
}

int solution(int _m, int _n, vector<vector<int>>& a) {
    // write code here
    m = _m, n = _n;
    int ans = 0;
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            ans = max(ans, dfs(a, i, j, false));
            ans = max(ans, dfs(a, i, j, true));
        }
    }
    return ans - 1; // 注意:这里需要 -1
}

int main() {
    vector<vector<int>> a1 = { {1, 2}, {4, 3} };
    cout << (solution(2, 2, a1) == 3) << endl;

    vector<vector<int>> a2 = { {10, 1, 6}, {5, 9, 3}, {7, 2, 4} };
    cout << (solution(3, 3, a2) == 8) << endl;

    vector<vector<int>> a3 = { {8, 3, 2, 1}, {4, 7, 6, 5}, {12, 11, 10, 9}, {16, 15, 14, 13} };
    cout << (solution(4, 4, a3) == 11) << endl;
}