问题描述:
小蓝准备在一个空旷的场地里面滑行,这个场地的高度不一,小蓝用一个 n 行 m 列的矩阵来表示场地,矩阵中的数值表示场地的高度。
如果小蓝在某个位置,而他上、下、左、右中有一个位置的高度(严格)低于当前的高度,小蓝就可以滑过去,滑动距离为 1 。
如果小蓝在某个位置,而他上、下、左、右中所有位置的高度都大于等于当前的高度,小蓝的滑行就结束了。
小蓝不能滑出矩阵所表示的场地。
小蓝可以任意选择一个位置开始滑行,请问小蓝最多能滑行多远距离。
输入第一行包含两个整数 n, m,用一个空格分隔。
接下来 n 行,每行包含 m 个整数,相邻整数之间用一个空格分隔,依次表示每个位置的高度。
输出一行包含一个整数,表示答案。
对于 30% 评测用例,1 <= n <= 20,1 <= m <= 20,0 <= 高度 <= 100。 对于所有评测用例,1 <= n <= 100,1 <= m <= 100,0 <= 高度 <= 10000。
样例输入
4 5
1 4 6 3 1
11 8 7 3 1
9 4 5 2 1
1 3 2 2 1
样例输出
7
样例说明
滑行的位置以此为
(2,1),(2,2),(2,3),(3,3),(3,2),(4,2),(4,3)。
-
每个位置都要经历以下的步骤寻找出路
-
代码实现 (此代码在考试时敲得,可能会出现一些错误,如有错误,请多多指正)
// 爆搜(会超时只能过30%的样例)
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int a[N][N],b[N][N];
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};//偏移量技巧
int n,m;
int dfs(int x,int y)
{
int cnt=0;// 初始值为0
for(int i=0;i<4;i++)
{
int nx=x+dx[i],ny=y+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&!b[nx][ny]&&a[nx][ny]<a[x][y])// 判断是否在边界以内,是否是第一次遍历,是否满足题中所给的滑倒下一个区域的条件
{
b[nx][ny]=1;// 表示该位置已经走过一次
cnt=max(cnt,dfs(nx,ny));
b[nx][ny]=0;// 回溯 恢复现场
}
}
return cnt+1;// 算上自身 cnt加1
}
int main ()
{
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&a[i][j]);// 打蓝桥杯的时候,输入输出尽量用scanf和printf,不然容易卡时间
}
}
int res=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
b[i][j]=1;// 表示被遍历过一次
res=max(res,dfs(i,j));
b[i][j]=0;// 恢复现场
}
}
printf("%d\n",res);
return 0;
}
// 记忆化搜索(用另一个数组记录该点经过DFS后得到的最大滑行距离)
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int a[N][N],d[N][N];// 记忆化搜索中d[N][N]不仅代表该点是否遍历过,且表示该点DFS后的最远距离
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
int n,m;
int dfs(int x,int y)
{
int cnt=0;
if(d[x][y]!=-1) return d[x][y];//如果该点在记忆化数组中 直接返回
for(int i=0;i<4;i++)
{
int nx=x+dx[i],ny=y+dy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]<a[x][y])
{
cnt=max(cnt,dfs(nx,ny));//寻找该点所能遍历的长度的最大值
}
}
d[x][y]=cnt+1; //记录该点
return d[x][y];
}
int main ()
{
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%d",&a[i][j]);// 打蓝桥杯的时候,输入输出尽量用scanf和printf,不然容易卡时间
}
}
memset(d,-1,sizeof d);
int res=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
res=max(res,dfs(i,j));
}
}
printf("%d\n",res);
return 0;
}