編程題#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