编程题#2: 滑雪
来源: POJ (http://bailian.openjudge.cn/practice/1088/)
注意: 总时间限制: 1000ms 内存限制: 65536kB
描述
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。
输出
输出最长区域的长度。
样例输入
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
思路:
L(i,j)表示从点(i,j)出发的最长滑行长度。
一个点(i,j), 如果周围没有比它低的点, L(i,j) = 1
每个点的 L 值都初始化为1
将所有点按高度从小到大排序,从小到大遍历所有的点,用 multimap 容器实现
经过一个点(i,j)时,用递推公式求L(i,j)
程序解答:
#include <iostream>
//#include <memory>
#include <map>
#include <algorithm>
using namespace std;
struct coordinate{ //高度的坐标类
int x, y;
};
//C++ STL中Map的按Key排序和按Value排序 https://www.cnblogs.com/lakeone/p/5599047.html
//自定义map容器中的比较大小顺序,按Key排序
struct MyCompare{
bool operator()(const int& a, const int& b){ //这里或者写成 bool operator()(int a, int b) const{ http://zh.cppreference.com/w/cpp/algorithm/sort
return a < b;
}
};
int main() {
int R, C;
int L[102][102]; //滑行长度
int H[102][102]; //高度
//memset(L, 1, sizeof(L)); //memset函数直接将数组中的元素全部置成 1 http://zh.cppreference.com/w/cpp/string/byte/memset
//memset(H, 10000, sizeof(H)); //所有位置的高度全部置为 10000,此处不行! http://blog.csdn.net/my_business/article/details/40537653
for (int i = 0; i < 102; i++){
for (int j = 0; j < 102; j++){
L[i][j] = 1;
H[i][j] = 10000;
//cout << L[i][j] << " " << H[i][j] << " ";
}
//cout << endl;
}
int maxL = 0;
coordinate position;
multimap<int, coordinate, MyCompare> height; //这里要用multimap容器,因为可能出现相同高度的位置点!
multimap<int, coordinate, MyCompare>::iterator hi;
cin >> R >> C;
for (int i = 1; i <= R; i++){
for (int j = 1; j <= C; j++){
cin >> H[i][j];
position.x = i;
position.y = j;
height.insert({ H[i][j], position }); //把每个位置的高度和坐标放入map容器中
}
}
int Lx, Ly; //位置的坐标
for (hi = height.begin(); hi != height.end(); hi++){
//cout << hi->first << " " << hi->second.x << " " << hi->second.y << " " << H[hi->second.x][hi->second.y] << endl;
Lx = hi->second.x;
Ly = hi->second.y;
if (H[Lx][Ly] <= H[Lx - 1][Ly] && H[Lx][Ly] <= H[Lx + 1][Ly] && H[Lx][Ly] <= H[Lx][Ly - 1] && H[Lx][Ly] <= H[Lx][Ly + 1]){
L[Lx][Ly] = 1;
}
else{
if (H[Lx][Ly] > H[Lx - 1][Ly])
L[Lx][Ly] = max(L[Lx][Ly], L[Lx - 1][Ly] + 1);
if (H[Lx][Ly] > H[Lx + 1][Ly])
L[Lx][Ly] = max(L[Lx][Ly], L[Lx + 1][Ly] + 1);
if (H[Lx][Ly] > H[Lx][Ly - 1])
L[Lx][Ly] = max(L[Lx][Ly], L[Lx][Ly - 1] + 1);
if (H[Lx][Ly] > H[Lx][Ly + 1])
L[Lx][Ly] = max(L[Lx][Ly], L[Lx][Ly + 1] + 1);
}
if (maxL < L[Lx][Ly])
maxL = L[Lx][Ly];
}
cout << maxL << endl;
return 0;
}
其它解法参考:
https://www.cnblogs.com/Konayuki2015/p/4514285.html
http://www.cnblogs.com/dagon/p/4849857.html