问题描述
资源限制
时间限制: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;
}