问题描述
小U决定在一个 的地图上行走。地图中的每个位置都有一个高度,表示地形的高低。小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
问题理解
-
地图移动规则:
- 小U只能在高度不同的位置之间移动。即高度相同的跳过
- 移动时必须交替进行:上坡后必须下坡,下坡后必须上坡。需要一个变量来记录上一次移动是上坡还是下坡
- 每个位置只能经过一次,不能重复行走。需要定义一个vis数组来存储是否被访问过,要记得回溯。
-
目标:
- 找到小U在地图上可以移动的最大次数,即在符合所有条件的前提下,小U能走过的最大连续位置数量。
数据结构
- 二维数组:用于表示地图的高度。
- 访问标记数组:用于记录每个位置是否已经被访问过。
算法步骤
-
深度优先搜索 (DFS):
- 从每个位置开始,进行深度优先搜索,尝试找到最长的路径。
- 在DFS过程中,需要记录当前的移动方向(上坡或下坡),并确保下一次移动的方向与当前方向相反
-
状态记录:
- 在DFS过程中,需要记录每个位置的访问状态,以避免重复访问。
- 每次移动时,更新当前位置的访问状态,并在回溯时恢复状态。
-
边界条件:
- 确保移动不会超出地图的边界。
- 确保移动到的位置高度与当前位置不同。
代码分析
通过深度优先搜索(DFS)来遍历地图,确保每次移动都符合题目要求的交替上坡和下坡规则。通过递归调用DFS,计算从每个位置开始的最大移动次数,并更新全局最大值。整体思路清晰,逻辑正确。
-
dx和dy数组用于表示四个方向的移动:上、右、下、左。 -
x,y:当前位置的坐标。 -
d:上一次移动的方向,-1表示上一次是下坡,1表示上一次是上坡,0表示初始状态。 -
vis:访问标记数组,记录每个位置是否已经被访问过。 -
a:地图的高度数组。 -
m,n:地图的行数和列数。 -
逻辑:
- 遍历四个方向,计算新的坐标
nx,ny。 - 检查新坐标是否越界,是否已经被访问过,以及是否与当前位置高度相同。
- 检查当前移动方向是否符合交替规则(上坡后必须下坡,下坡后必须上坡)。
- 如果符合条件,标记新位置为已访问,并递归调用DFS。
- 在回溯时,恢复新位置的访问状态。
- 遍历四个方向,计算新的坐标
#include <iostream>
#include <vector>
using namespace std;
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
// d为-1表示上一次下坡,d为1表示上一次上坡
int dfs(int x, int y, int d, vector<vector<int>> vis, vector<vector<int>> a, int m, int n) {
int t = 0;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
if (vis[nx][ny]) continue;
if (a[nx][ny] == a[x][y]) continue;
if (d == 0 || (d == 1 && a[x][y] > a[nx][ny]) || (d == -1 && a[x][y] < a[nx][ny])) {
vis[nx][ny] = 1;
int td = 0;
if (a[nx][ny] > a[x][y]) td = 1;
else if (a[nx][ny] < a[x][y]) td = -1;
t = max(t, 1 + dfs(nx, ny, td, vis, a, m, n));
vis[nx][ny] = 0;
}
}
return t;
}
int solution(int m, int n, vector<vector<int>>& a) {
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
vector<vector<int>> vis(m, vector<int>(n, 0));
vis[i][j] = 1;
int x = dfs(i, j, 0, vis, a, m, n);
// cout << "www " << x << endl;
res = max(res, x);
}
}
return res;
}
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;
}