问题描述
小U决定在一个 m×nm×n 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小U只能在满足以下条件的情况下移动:
- 只能上坡或者下坡,不能走到高度相同的点。
- 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡,不能连续上坡或下坡。
- 每个位置只能经过一次,不能重复行走。
任务是帮助小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 的算法,对每个点进行两次 dfs ,注意两次分别是 上坡和下坡
- 这里我们用到 bool 值来标记上下坡
- 然后对于dfs 参数及返回值需要进行一下处理,返回值:返回当前[x, y]往下走的最大步数,参数:坐标以及上下坡标记
- 注意:由于当前点不算走一步,所以对于最后结果我们需要 -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;
}