zoukankan      html  css  js  c++  java
  • 【a901】滑雪

    Time Limit: 10 second
    Memory Limit: 2 MB

    问题描述
    滑雪是一项非常刺激的运动,为了获得速度,滑雪的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待 升降机来载你。给出一个由二维数组表示的滑雪区域,数组的数字代表各点的高度。请你找出这个区域中最长的滑坡。
    下面是一个例子:
    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更长。事实上,这是最长的一条滑坡。

    Input

    输入文件ski.in的第一行为两个数R, C,表示滑雪区域的行数和列数(1≤R,C≤100)。下面是R行,每行有C个整数,表示高度H(0≤H≤10000)。

    Output

    输出文件ski.out包括一行,只包含一个整数,表示滑雪区域中最长滑坡的长度。


    Sample Input

    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 
    

    Sample Output

    25
    
    【题解】
    这题很容易想到从每一个点都进行一次深搜。然后记录一下最长滑坡是多少就好。
    但是如果只是这样。没有办法通过100*100的数据(平台上的数据很水没有到100*100的。)
    所以要改进一下。
    加上一个f[x][y]数组,表示到x,y这个点后能下降多长的长度。因为某个点所能达到的最长长度是确定的,所以我们一旦访问到这个点直接返回f[x][y]这个值就可以了。这样可以节省很多时间。
    不,应该说每个点都只会访问一次。这个算法是最优的了。
    对了,这个叫记忆化搜索
    【代码】
    #include <cstdio>
    #include <cstring>
    
    const int dx[5] = {0,0,0,1,-1};
    const int dy[5] = {0,1,-1,0,0};
    
    int r,c,a[101][101],f[101][101],ma = 0;
    
    void input_data()
    {
    	scanf("%d%d",&r,&c);
    	for (int i = 1;i <= r;i++) //输入数据的过程 
    		for (int j = 1;j <= c;j++)
    			scanf("%d",&a[i][j]);
    	memset(f,255,sizeof(f)); //255表示给f数组全部赋值为-1 
    }
    
    int dfs(int x,int y) //尝试从x,y这个点开始下降 
    {
    	if (f[x][y] !=-1) //如果这个点之前已经找过了最长长度 
    		return f[x][y]; //则直接返回就可以了 
    	int m = 0;
    	for (int i = 1;i <= 4;i++) //否则往4个方向进行搜索 
    		{
    			int xx = x + dx[i],yy = y + dy[i];
    			if (xx < 1) continue;
    			if (xx > r) continue;
    			if (yy < 1) continue;
    			if (yy > c) continue; //越界的情况剔除掉 
    			if (a[xx][yy] < a[x][y]) //如果满足下降条件 
    				{
    					int te = dfs(xx,yy);
    					if (te > m) //从4个方向中找到最大的 
    						m = te;	
    				}
    		}
    	f[x][y] = m + 1; //加上本身是一个 所以加1 
    	return m+1; //返回给上一层 递归 
    }
    
    void get_ans()
    {
    	for (int i = 1;i <= r;i++) //从每个点都搜索一次 
    		for (int j = 1;j <= c;j++)
    			{
    				int temp = dfs(i,j);
    				if (temp > ma)
    					ma = temp;
    			}
    				
    }
    
    void output_ans()
    {
    	printf("%d",ma);	
    }
    
    int main()
    {
    	//freopen("F:\rush.txt","r",stdin);
    	input_data();
    	get_ans();
    	output_ans();
    	return 0;	
    }



  • 相关阅读:
    找球号(一)
    拦截导弹
    开灯问题
    超级台阶
    小学生算术
    Financial Management
    三角形面积
    另一种阶乘问题
    并发环境下,先操作数据库还是先操作缓存?
    Flask框架Server和RequestHandler的爱恨纠缠
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632360.html
Copyright © 2011-2022 走看看