nyoj10 skiing poj1088 滑雪

skiing

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 5
描述
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更长。事实上,这是最长的一条。
输入
第一行表示有几组测试数据,输入的第二行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C
个整数,代表高度h,0<=h<=10000。
后面是下一组数据;
输出
输出最长区域的长度。
样例输入
1
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
#include<cstdio>
#include<cstring>
int map[101][101];
int r,c;
int dp[101][101];

int fun(int y,int x) //上下左右判定 
{
	if(dp[y][x]>0) //已经处理过了 
	return dp[y][x];
	int left=0,right=0,up=0,down=0;
	//判断当前4个点的方向 
	if(y-1>=1)//边界判定 
	{
		if(map[y][x]>map[y-1][x])
		up=1+fun(y-1,x);
		else up=1;
	}
	else up=1;

    if(y+1<=r)
    {
    	if(map[y][x]>map[y+1][x])
    	down=1+fun(y+1,x);
    	else down=1;
	}
	else down=1;
	
	if(x-1>=1)
	{
		if(map[y][x]>map[y][x-1])
		left=1+fun(y,x-1);
		else left=1;
	}
	else left=1;

    if(x+1<=c)
    {
    	if(map[y][x]>map[y][x+1])
    	right=1+fun(y,x+1);
    	else right=1;
	}
	else right=1;
	
	//选择up,down,left,right 4个方向最大的值,返回  
	if(up<down) up=down;
	if(up<left) up=left;
	if(up<right) up=right;
	return up;
}

int main()
{
	int i,j,t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&r,&c);
		for(i=1;i<=r;i++)
		for(j=1;j<=c;j++)
		scanf("%d",&map[i][j]);
		
		memset(dp,0,sizeof(dp));
		int ans=0;
		for(i=1;i<=r;i++)
		for(j=1;j<=c;j++)
		{
			dp[i][j]=fun(i,j);
			if(ans<dp[i][j])//挑选出最长的区域长度 
			ans=dp[i][j];
		}
		printf("%d\n",ans);	
	}
	return 0;
}
#include<iostream>
using namespace std;
int map[101][101]={0};//存原始数据
int r,c;//行数,列数
int dis[101][101]={0};//存储节点的最长路径值

int fun(int form,int to)//form代表y坐标,to代表x坐标 而且要记住此时坐标系原点在左上角 
{
	if(dis[form][to]>0)//如果已经记录了值,直接返回
	return dis[form][to];
	
	int zuo=0,you=0,shang=0,xia=0;//每个点都有4个方向可以试着拓展 
	
	if(form+1<=r)//处理下路并剪枝
	{
		if(map[form][to]>map[form+1][to])//高度 比较 从高地方滑向低地方 
		xia=1+fun(form+1,to);
		else xia=1;
	}
	else xia=1;
	
	if(form-1>=1)//处理上路并剪枝
	{
		if(map[form][to]>map[form-1][to])
		shang=1+fun(form-1,to);
		else shang=1;
	}
	else shang=1;
	
	if(to+1<=c)//处理右路并剪枝
	{
		if(map[form][to]>map[form][to+1])
		you=1+fun(form,to+1);
		else you=1;
	}
	else you=1;
	
	if(to-1>=1)//处理左路并剪枝
	{
		if(map[form][to]>map[form][to-1])
		zuo=1+fun(form,to-1);
		else zuo=1;
	}
	else zuo=1;
	
	if(zuo<you)zuo=you;
	if(zuo<shang)zuo=shang;
	if(zuo<xia)zuo=xia;
	return zuo;//返回最大值
}

int main()
{
	int i,j;
	cin>>r>>c;
	for(i=1;i<=r;i++)
		for(j=1;j<=c;j++)
			cin>>map[i][j];
			
	int ans=0;
	for(i=1;i<=r;i++)
		for(j=1;j<=c;j++)
		{
			dis[i][j]=fun(i,j);//记录每个节点的最长路径 
			//printf("%d\n",dis[i][j]); 
			if(ans<dis[i][j])
			ans=dis[i][j];//选出最大长度
		}
	cout<<ans<<endl;
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值