[算法]DP(抽象bfs)——滑雪

题目描述

区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
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。

输出:
输出最长区域的长度。

示例:

输入: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

思路

转化为bfs问题,先遍历矩阵,找出四个方向的高度都大于等于自己的节点,插入队列,然后按照bfs的方法搜索全图,边遍历边更新便利到结点的结果。

实现

#include <iostream>
#include <queue>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

#define MAXROWS 100
#define MAXCOLUMNS 100

using namespace std;


//c++的struct与c有所不同
struct Pot{
	int row;
	int column;
};

int heights[MAXROWS][MAXCOLUMNS];
int s[MAXROWS][MAXCOLUMNS];

int delta[][2] = {{-1,0},{1,0},{0,-1},{0,1}};

queue<Pot> visit;


//抽象bfs 
int main(int argc, char** argv) {
	int rows;
	int columns;
	int height;
	int rowi;
	int columni;
	bool isZeroS;
	int temp;
	int res;
	int row;
	int column;
	
	while(scanf("%d",&rows)!=EOF){
		scanf("%d",&columns);
		
		res = 1;
		
		for(row=0;row<rows;row++){
			for(column=0;column<columns;column++){
				scanf("%d",&heights[row][column]);
			}
		}
		
		
		for(row=0;row<rows;row++){
			for(column=0;column<columns;column++){
				height=heights[row][column];
				isZeroS = true;
				s[row][column] = 1; //不像java每次new一个新记录矩阵,c++这种预先开数组的每轮需要初始化 
				
				for(int i=0;i<4;i++){
					rowi = row+delta[i][0];
					columni = column+delta[i][1];
					
					if(rowi<0 || rowi>=rows || columni<0 || columni>=columns || heights[rowi][columni]>=height) continue;
					
					isZeroS = false;
					break;
				}
				
				if(isZeroS){
					Pot pot;
					pot.row = row;
					pot.column = column;
					 
					visit.push(pot);
				}
				
			}
		}	
		
		
		while(!visit.empty()){
			Pot pot = visit.front();
			visit.pop();
			row = pot.row;
			column = pot.column;
				
			height = heights[row][column];
			temp = s[row][column]+1;
			
			for(int i=0;i<4;i++){
				rowi = row+delta[i][0];
				columni = column+delta[i][1];
					
				if(rowi>=0 && rowi<rows && columni>=0 && columni<columns && heights[rowi][columni]>height && temp>s[rowi][columni]){
					s[rowi][columni] = temp;
					
					if(temp>res) res=temp;
					
					Pot potT;
					potT.row = rowi;
					potT.column = columni;
					visit.push(potT);
				}
					
			}
		} 
		printf("%d\n",res);
	}
	
	return 0;
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值