问题 B: 滑雪
时间限制: 1 Sec 内存限制: 128 MB
提交: 270 解决: 188
[提交][状态][讨论版]
题目描述
Michael喜欢滑雪百这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
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<=100000000。
输出
输出最长区域的长度。
样例输入
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
提示
题目思路:这道题目可以用深搜的思想解决,考虑将每一个元素都进行深搜,深搜过程是:判断这个元素的邻位(上下左右)如果非-1,并且比这个元素的值小,则以这个邻位元素为起点继续下一层的深搜,并且长度len要加1,同时需要先将上一个元素标记为-1(记得在循环完所有邻位元素之后要把元素的值放回去,不然会影响其它点的深搜结果)。 之后再判断len是否为最大,是的话则赋值给最大值保存。
代码实现:
package com.eangaie.main.lanqiaobeiDP;
import java.util.*;
/** * * @CreateTime 2018年3月16日下午8:19:33 * * @author谢彦杰 * * @since JDK 1.8 * * 文件名称:B.java * * 滑雪问题 **/
public class B {
/* 储存最大长度 */ static int Maxlen = Integer.MIN_VALUE; /* 方向数组 */ static int[][] dir = { { -1, 0 }, { 0, 1 }, { 0, -1 }, { 1, 0 } }; static int[][] arr; static int len = 1;
public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); int i, j, R, C; R = in.nextInt(); C = in.nextInt(); arr = new int[R + 2][C + 2]; /* 初始化 */ for (i = 0; i < R + 2; i++) { for (j = 0; j < C + 2; j++) { arr[i][j] = -1; } } /* 填数 */ for (i = 1; i < R + 1; i++) { for (j = 1; j < C + 1; j++) { arr[i][j] = in.nextInt(); } } for (i = 1; i < R + 1; i++) { for (j = 1; j < C + 1; j++) { dfs(i, j); } } System.out.println(Maxlen); }
private static void dfs(int x, int y) { int i; int num = arr[x][y]; arr[x][y] = -1; /* 如果周边有数字比他小并且不等于-1,则进入下一步,若不存在数字比他小,则说明这次深搜的len已经是本轮最长 */ for (i = 0; i < 4; i++) { if (arr[x + dir[i][0]][y + dir[i][1]] != -1 && arr[x + dir[i][0]][y + dir[i][1]] < num) { len++; dfs(x + dir[i][0], y + dir[i][1]); len--; } } arr[x][y]=num; Maxlen = Maxlen < len ? len : Maxlen; }
} |