25
这题其实是搜索题,要用到记忆化搜索,就是把未搜索的点标记, 若已经搜索到并已经赋值,就可以直接用了,代码已经注释。
# include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int x[4]={0, 0, 1, -1};//枚举上下左右四个方向 int y[4]={1, -1, 0, 0};//枚举上下左右四个方向 int r, c;//行列 int dp[110][110];//即每个点出发的最大值,未求的点赋为-1 int a[110][110];//存输入数据 int d(int n, int m);//传入一个点的坐标,返回从该点出发的最大值 int main(){ int t, i, j, k; int _max;//存最大值,即最后的答案 scanf("%d", &t);//测试数据的组数 for(j=0; j<=109; j++){ a[0][j]=10000;//边界赋为最大值 a[j][0]=10000;//<span style="font-family: Arial, Helvetica, sans-serif;">边界赋为最大值</span> } for(i=1; i<=t; i++){ scanf("%d%d", &r, &c); _max=-200000000;//最大值先初始化为最小 memset(dp, -1, sizeof(dp));//未求值的点先初始化为-1 for(j=1; j<=c+1; j++){ a[r+1][j]=10000;//边界初始化为最大值 } for(j=1; j<=r+1; j++){ a[j][c+1]=10000;//边界初始化为最大值 } for(j=1; j<=r; j++){ for(k=1; k<=c; k++){ scanf("%d", &a[j][k]);//读入数据 } } for(j=1; j<=r; j++){ for(k=1; k<=c; k++){ dp[j][k]=d(j, k);//得到该点出发的最大距离 _max=max(dp[j][k], _max);//与最大值进行比较 } } printf("%d\n", _max); } return 0; } int d(int n, int m){ int _d[4];//存从改点出发的四个方向最大值 int flage=0, max=0;//若四个相邻方向中有一个高度比当前高度小,则flage=1; memset(_d, 0, sizeof(_d)); for(int i=0; i<=3; i++){ if(a[n][m]>a[n+x[i]][m+y[i]]){ flage=1; if(dp[n+x[i]][m+y[i]]>=0){//该点已经搜索过,可以直接用 _d[i]=dp[n+x[i]][m+y[i]]+1; } else{ _d[i]=1+d(n+x[i], m+y[i]);//改点还没搜索过,继续递归调用 } } } if(flage){ sort(_d, _d+4); return _d[3];//返回最大值 } return 1;//若flage=0,即周围没有高度比这点小,则返回1,因为本身算为长度1; }