leetcode第一题:滑雪问题

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 <= 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

Output

扫描二维码关注公众号,回复: 4081091 查看本文章

输出最长区域的长度。

25

这个题目我的思路很简单,就是对每一个点进行深度搜索,得到每一个点的最大路径,然后取出所有最大路径。但要注意的是,为了避免重复搜索,所以需要定义一个count二维数组,来记下已经搜索过的结果。

下面是我自己写的代码:

#include <iostream>
#include<cstdio>
#include <time.h>
#include <cstring>

int h[100][100]={0};   ////高度图
int count[100][100]={0};  ///记录每一个高点的最大滑雪长度
int f[][2]={{1,0},{0,1},{-1,0},{0,-1}};  ///这个在注释的代码有用,在做dfs的时候用这个,整个的dfs会显得简洁
int r,c;
int max_line = 0;

int find(int i,int j)
{
    int max_t=0;
    if(count[i][j]>0)
        return count[i][j];
    /////up search
    if(i-1>=0)
    {
        if(h[i-1][j]<h[i][j])
        {
            max_t = std::max(find(i-1,j),max_t);
        }
    }
    /////down search
    if(i+1<r)
    {
        if(h[i+1][j]<h[i][j])
        {
            max_t = std::max(find(i+1,j),max_t);
        }
    }
    ////left search
    if(j-1>=0)
    {
        if(h[i][j-1]<h[i][j])
           max_t = std::max(find(i,j-1),max_t);
    }
    //////right search
    if(j+1<c)
    {
        if(h[i][j+1]<h[i][j])
        {
            max_t = std::max(find(i,j+1),max_t);
        }
    }
///如果用下面的代码,那么这个函数以上四个遍历都可以注释掉了,这个是我参考网友的写法写的比较简洁,但思路一样,并不影响速度
//    for ( int z = 0 ; z < 4 ; z ++ )
//    {
//        int s = i + f[z][0] ;
//        int t = j + f[z][1] ;
//        if ( s < 0 || t < 0 || s >= r || t >= c )
//            continue;
//        if ( h[s][t] >= h[i][j] )
//            continue;
//        max_t = std::max ( max_t , find ( s , t ) ) ;
//    }
    count[i][j]=max_t+1;    /////关键步骤,记下每一次深度搜索的结果,避免重复搜索
    return max_t+1; /////如以上没有一个满足条件,就可以直接+1,由于递归,所以只要是经过的点都+1,刚好记录下深度信息
}
int main() {
    memset( count , -1 , sizeof ( count ) );
    scanf("%d%d", &r, &c);  ////scanf 是以回车一下作为输入数据的间隔
    printf("input h data");
    for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++)
        {
            scanf("%d", &h[i][j]);
   //           h[i][j]=i+j;

        }
    clock_t start=clock();
    int ans = 0;
    for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++)
        {
            count[i][j]=find(i,j);
            ans = std::max(ans, count[i][j]);
        }
    clock_t end=clock();
    std::cout<<"cost time :"<<double(end-start)/CLOCKS_PER_SEC*1000 <<"s"<<std::endl;
    printf("%d", ans);
    return 0;
}

该算法主要的思路就是记忆搜索,此算法在计算100*100的数组时,只需要1.394s完成计算,如果不采用记忆的话,算法直接卡死。

猜你喜欢

转载自blog.csdn.net/qq_31638535/article/details/83274584
今日推荐