【蓝桥杯】试题 算法提高 最长滑雪道

问题描述

资源限制
  时间限制:1.0s 内存限制:256.0MB
问题描述
  小袁非常喜欢滑雪, 因为滑雪很刺激。为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。 小袁想知道在某个区域中最长的一个滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。如下:在这里插入图片描述
  一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。
  你的任务就是找到最长的一条滑坡,并且将滑坡的长度输出。 滑坡的长度定义为经过点的个数,例如滑坡24-17-16-1的长度是4。
  
输入格式  
  输入的第一行表示区域的行数R和列数C(1<=R, C<=10)。下面是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

解题思路

该题目比较简单,只需要按照题意进行模拟,计算每一点出发可以走的最长路线,并进行比较保留最长路线值。
  需要注意的是,不一定从最大值出发的路线会是最长路线,可能会存在类似
55 66 48 53 52
64 15 19 16 94
68 18 100 23 92
95 85 13 98 89
86 88 87 84 85
这样的死路,因此必须每一个点都需要作为出发点进行模拟计算,最后比较得到结果。

解题代码

//初始代码,从最大值开始计算,且不用一点点脑子
#include<iostream>
using namespace std;
int a[11][11];
int m,n;
int dfs(int i,int j)
{
     int res=0;
     int tmp=0;
     if(i<0||j<0||i>=n||j>=m) tmp=0;
         else  tmp=1;
     if(i>=1&&j>=0&&a[i-1][j]<a[i][j])
          tmp+=dfs(i-1,j);
     res=max(res,tmp);
     tmp=1;
     if(i<=n-2&&j>=0&&a[i+1][j]<a[i][j])
        tmp+=dfs(i+1,j);
     res=max(res,tmp);  
     tmp=1;
     if(i>=0&&j>=1&&a[i][j-1]<a[i][j])
        tmp+=dfs(i,j-1);
     res=max(res,tmp);      
     tmp=1;
     if(i>=0&&j<=m-2&&a[i][j+1]<a[i][j])
        tmp+=dfs(i,j+1);
     res=max(res,tmp);    
     return res;
}
int main()
{
     cin>>n>>m;
     int max=0,c=0,r=0;
     for(int i=0;i<n;i++)
          for(int j=0;j<m;j++)
          {
               cin>>a[i][j];
               if(a[i][j]>max)
               {
                   max=a[i][j];
                   c=i;r=j;
               }    
          }
     int res=dfs(c,r);
     cout<<res;
     return 0;
 } 
//找到错误后,参考简洁版代码
#include<iostream>
#include<cstring>
using namespace std;
int ans=0;
int map[10][10];
int vis[10][10]; 
//向上,向下,向左,向右 
int mx[4]={0,0,-1,1};
int my[4]={-1,1,0,0};
int a,b;
int dfs(int x,int y,int step)
{
     ans=max(ans,step);
     for(int i=0;i<4;i++)
     {
          int xx=x+mx[i];
          int yy=y+my[i];
          if(xx>=0&&xx<a&&yy>=0&&yy<b&&!vis[xx][yy]&&map[xx][yy]<map[x][y])
          {
               vis[xx][yy]=1;
               dfs(xx,yy,step+1);
               vis[xx][yy]=0;
          }
      } 
      return ans;
 } 
int main()
{
     cin>>a>>b;
     for(int i=0;i<a;i++)
          for(int j=0;j<b;j++)
               cin>>map[i][j];
     for(int i=0;i<a;i++)
          for(int j=0;j<b;j++)
          {
               memset(vis,0,sizeof vis);  
               vis[i][j]=1;
               dfs(i,j,1);
          }
     cout<<ans;
     return 0;
 } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值