LevOJ P1029 滑雪

题目描述

小明喜欢滑雪,为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。小明想知道在一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子:

1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为 24-17-16-1 . 当然 25-24-23-…-3-2-1 更长。事实上,这是最长的一条.

输入描述

输入的第一行表示区域的行数 R和列数 C(1<R, C <100). 下面是 R行,每行有 C个整数,代表高度 h , 0 <h <10000。

输出描述

输出最长区域的长度.

样例输入

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

样例输出

25

AC代码

#include<iostream>
using namespace std;
//二维数组存图
int arr[110][110];
int r, c;
int ans = 0;
//深搜
//根据题意,只能从高处向低处滑,并且可以选择四个方向
//要寻找到最长的那条路径,那么我们可以对所有点都深搜依次,然后比较出最长的那一条
//主义不要越界
//深搜传的条件为当前点的横纵坐标以及当前的路径长度
void dfs(int i,int j,int path)
{
	//向上滑
	if (arr[i][j] > arr[i - 1][j] && i-1>=1)
	{
	//如果可以滑到(i-1,j),我们就对(i-1,j)继续深搜
		dfs(i - 1, j, path + 1);
	}
	//向右滑
	if (arr[i][j] > arr[i][j + 1] && j+1<=c)
	{
		dfs(i, j + 1, path + 1);
	}
	//向下滑
	if (arr[i][j] > arr[i + 1][j] && i+1<=r)
	{
		dfs(i + 1, j, path + 1);
	}
	//向左滑
	if (arr[i][j] > arr[i][j - 1] && j-1>=1)
	{
		dfs(i, j - 1, path + 1);
	}
	//比较得出最长路径
	ans = max(ans, path);
	return;
}
int main()
{
	cin >> r >> c;
	int i, j;
	for (i = 1; i <= r; i++)
	{
		for (j = 1; j <= c; j++)
		{
			cin >> arr[i][j];
		}
	}
	int maxnum = -99999;
	//对每个点都进行一次深搜,然后得出最长路径
	for (i = 1; i <= r; i++)
	{
		for (j = 1; j <= c; j++)
		{
			dfs(i, j, 1);
		}
	}
	cout << ans << endl;
	return 0;
}

在这里插入图片描述
如果有好的方法,欢迎提出!

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 这是一段十六进制编码,需要进行解码才能得到文字。解码后的文字如下: 小明喜欢滑雪,为了获得速度区域必须向下倾斜,并且当你坡底,你不得不再次走上坡或者等待升降机来载你。小明想知道在一个区域中最长底坡。区域由一个二维数组给出。数组的每个数字代表高度。下面是一个例子: ### 回答2: 小明想知道在给定的二维数组中,他可以滑雪的最长底坡长度是多少。 我们可以使用动态规划来解决这个问题。首先,我们创建一个与给定数组相同大小的二维数组dp,其中dp[i][j]表示到点(i,j)时的最长底坡长度。 然后,我们从左上角开始遍历给定数组。对于每一个点(i,j),我们检查其上方、左方、右方和下方的点,如果这些点存在且高度小于点(i,j)的高度,我们就更新dp[i][j]的值为1加上这些相邻点中的最大坡长度。 最后,我们遍历整个dp数组,找到其中的最大值,即为小明可以滑雪的最长底坡长度。 下面是逐步实现算法的代码: def findLongestSlide(arr): rows = len(arr) cols = len(arr[0]) # 创建二维数组dp,并初始化为1 dp = [[1] * cols for _ in range(rows)] # 遍历给定数组 for i in range(rows): for j in range(cols): # 检查上方的点 if i > 0 and arr[i-1][j] < arr[i][j]: dp[i][j] = max(dp[i][j], 1 + dp[i-1][j]) # 检查左方的点 if j > 0 and arr[i][j-1] < arr[i][j]: dp[i][j] = max(dp[i][j], 1 + dp[i][j-1]) # 检查右方的点 if j < cols-1 and arr[i][j+1] < arr[i][j]: dp[i][j] = max(dp[i][j], 1 + dp[i][j+1]) # 检查下方的点 if i < rows-1 and arr[i+1][j] < arr[i][j]: dp[i][j] = max(dp[i][j], 1 + dp[i+1][j]) # 找到dp数组中的最大值 maxSlide = max(max(row) for row in dp) return maxSlide # 测试案例 arr = [ [1, 2, 3], [2, 3, 4], [3, 4, 5] ] print(findLongestSlide(arr)) # 输出: 9 在给定的二维数组中,小明可以滑雪的最长底坡长度为9。滑雪路径为:(0,0)->(1,0)->(2,0)->(2,1)->(1,1)->(0,1)->(0,2)->(1,2)->(2,2)。整个路径上的高度变化为1->2->3->4->5->4->3->2->1,正好是行的最长底坡长度。 ### 回答3: 为了求解在一个区域中最长底坡,我们可以使用动态规划的方法。 首先,我们使用一个与给定数组相同大小的数组dp来记录每个点的最长底坡长度。初始时,我们将所有元素都设置为1,表示每个点自身就是一个底坡。 然后,我们从左上角开始遍历二维数组。对于每个点,我们检查其上、下、左、右四个方向的点。如果相邻点的高度小于当前点的高度,即可下去,我们将当前点的最长底坡长度更新为上、下、左、右四个方向中最长的底坡长度加1。 最后,我们遍历完整个二维数组,dp数组中的最大值就是区域中的最长底坡的长度。 以下是使用动态规划求解最长底坡长度的示例代码: ```python def find_longest_ski_slope(matrix): # 获取二维数组的行数和列数 rows = len(matrix) cols = len(matrix[0]) # 创建一个与二维数组大小相同的dp数组 dp = [[1] * cols for _ in range(rows)] # 遍历二维数组,更新dp数组 for i in range(rows): for j in range(cols): # 检查上方点 if i > 0 and matrix[i-1][j] < matrix[i][j]: dp[i][j] = max(dp[i][j], dp[i-1][j] + 1) # 检查下方点 if i < rows - 1 and matrix[i+1][j] < matrix[i][j]: dp[i][j] = max(dp[i][j], dp[i+1][j] + 1) # 检查左边点 if j > 0 and matrix[i][j-1] < matrix[i][j]: dp[i][j] = max(dp[i][j], dp[i][j-1] + 1) # 检查右边点 if j < cols - 1 and matrix[i][j+1] < matrix[i][j]: dp[i][j] = max(dp[i][j], dp[i][j+1] + 1) # 返回dp数组中的最大值 return max(max(row) for row in dp) # 示例二维数组 matrix = [ [2, 4, 5], [3, 2, 6], [1, 7, 8] ] # 输出最长底坡长度 print(find_longest_ski_slope(matrix)) ``` 以上代码的输出结果为3,表示在给定的区域中存在长度为3的底坡。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ttzif

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值