zoukankan      html  css  js  c++  java
  • 滑雪

    滑雪

    Problem Description

    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更长。事实上,这是最长的一条。

    Input

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

    Output

    输出最长区域的长度。

    Sample Input

    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

    Sample Output

    25

    解释:

    一道搜索题,找一条最长的路,我最先一开始想的是,从一个点出发,如果它可以去下一个点,那么我就判断一下是不是可以进行更新其最长的距离,然后再去找下一个点,然后记录当前的最长路径,以方便剪枝。然后就是超内存,超时,运行错误,各种问题。发现自己搞不定,想不到一个解决办法,按照我之前的思路写下去,于是百度。

    对于一个点而言它的最长距离,肯定是从它的四个方向过来的。一次类推,假设一个点是有左边的点更新的,左边的点又是由左边的过来的,一直推下去,当一个点的最短距离确定时,就已经可以确定所有与它有关的,包括间接的点了,并且每一个点都需要需要判断一次,而不再是重复计算了。采用后更新的方式。就是在递归的归过程中更新。这样可以避免许多不必要的循环。

    自己还是习惯于在递的过程中更新,在归的过程中去恢复状态,这次学到了,在归的过程中去更新,可以省很多事。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 const int N  = 2110;
     5 const int INF = 1314520;
     6 struct point {
     7   int height;
     8   int max_lenght;
     9 }ski_map[N][N];
    10 
    11 int R, C;
    12 int max_res;
    13 
    14 int dir[][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
    15 
    16 int Scan() { //输入外挂
    17   int res = 0, ch, flag = 0;
    18   if ((ch = getchar()) == '-')
    19     flag = 1;
    20   else if (ch >= '0' && ch <= '9')
    21     res = ch - '0';
    22   while ((ch = getchar()) >= '0' && ch <= '9')
    23     res = res * 10 + ch - '0';
    24   return flag ? -res : res;
    25 }
    26 
    27 void init() {   // 初始化, 在R*C的地图上面有一个方框包裹起来
    28   for (int i = 0; i <= R+2; i++) {
    29     ski_map[i][0].height = ski_map[i][C+1].height = INF;
    30   }
    31 
    32   for (int i = 0; i <= C+2; i++) {
    33     ski_map[0][i].height = ski_map[R+1][i].height = INF;
    34   }
    35 }
    36 
    37 int search (int x, int y) {
    38   int max_len = 0, len = 0;
    39   ski_map[x][y].max_lenght = 1;
    40 
    41   for (int i = 0; i < 4; i++) {
    42     int tx = x + dir[i][0];
    43     int ty = y + dir[i][1];
    44     if (tx <= 0 || tx > R || ty <= 0 || ty > C) continue;
    45     if (ski_map[x][y].height > ski_map[tx][ty].height) {  //   表示这个(x, y)可以滑到 (tx, ty) 位置去
    46       if (ski_map[tx][ty].max_lenght == 0) {  //  表示(tx,ty)这个位置,还没有被滑到过,如果滑到了,当前最大滑行距离就是上一次的滑行距离。
    47         len = search(tx, ty);
    48       } else {
    49         len = ski_map[tx][ty].max_lenght;
    50       }
    51       max_len = max(len, max_len);
    52     } 
    53 
    54    
    55   }
    56   return ski_map[x][y].max_lenght += max_len; //   从四个方向中选择最大一个滑行距离
    57 }
    58 
    59 int main () {
    60 
    61   while (~scanf("%d %d", &R, &C)) {
    62     max_res = 0;
    63     init();
    64     for (int i = 1; i <= R; i++) { //  读入数据
    65       for (int j = 1; j <= C; j++) {
    66        ski_map[i][j].height = Scan();
    67        ski_map[i][j].max_lenght = 0;
    68         
    69       }
    70     } 
    71 
    72     for (int i = 1; i <= R; i++) { //遍历每一个点,采用后更新
    73       for (int j = 1; j <= C; j++) {
    74         if (ski_map[i][j].max_lenght == 0) {
    75           int len = search(i, j);
    76           max_res = max(max_res, len);
    77         }
    78       }
    79     }
    80 
    81     printf("%d
    ", max_res);
    82   }
    83   return 0;
    84 }
    View Code
  • 相关阅读:
    两台虚拟机(不同电脑)通信
    虚拟机使用网络助手
    strcpy_s
    线程创建几种方法
    JavaWeb——EL详解
    JavaWeb_EL语法
    JavaWeb_JavaBean
    JavaWeb_HttpSession之验证码
    JavaWeb_HttpSession之表单的重复提交
    JavaWeb——相对路径和绝对路径
  • 原文地址:https://www.cnblogs.com/gznb/p/11211859.html
Copyright © 2011-2022 走看看