#include <iostream>
#include <vector>
#include <limits.h>
using namespace std;
/**
* 计算动态数组里代表的地貌土堆高度组成的天际线里, 仿真的坑凹状可以容纳的水量数?
* */
int calcWaterStore(vector<int>& vec)
{
if (vec.size() < 3) {
return 0;
}
///< 递增序列,则直接忽略,削减问题规模为子问题;否则出现了U型坑道,则才有可能积存水量
auto iter = vec.begin();
auto nextIter = vec.begin() + 1;
for (; nextIter != vec.end(); ++iter, ++nextIter) {
if (*iter > *nextIter) {
break; ///< 出现了下降趋势有出现坑凹的趋势,则跳出
}
}
if (nextIter == vec.end()) {
return 0; ///< 说明是严格递增序列,肯定存不住水
}
vec.erase(vec.begin(), iter);///< 删除这部分递增序列
if (vec.size() < 3) { ///< 剩余元素数量不够3,挡板存不住水量,直接返回0
return 0;
}
///< 计算可能出现的一个U型坑道的积水---先下降后上升,找出水位线最右侧元素的值和出现的准确位置
iter = vec.begin();
nextIter = vec.begin() + 1;
int waterLevelMax = INT_MIN;
auto rightMostAt = nextIter;
for (; nextIter != vec.end(); ++nextIter) {
if (*nextIter >= vec.front()) { ///< 木桶效应,低端优先,可以做个小结算了
waterLevelMax = vec.front();
rightMostAt = nextIter; ///< 虚设的水位线上限
break;
}
///< 寻找影响坑凹水位线的隔板元素,即第二大元素
if (*nextIter > waterLevelMax) {
waterLevelMax = *nextIter;
rightMostAt = nextIter;
}
}
if (rightMostAt != vec.begin() + 1) {
int sum = 0;
for (auto iter1 = vec.begin() + 1; iter1 != rightMostAt; ++iter1) {
sum += (waterLevelMax - *iter1);
}
vec.erase(vec.begin(), rightMostAt);///< 消减此子序列
return sum + calcWaterStore(vec);
}
else
{
vec.erase(vec.begin());///< 问题规模减少1个
return calcWaterStore(vec);
}
}
int main(int argc, char** argv)
{
std::vector<int> v1 = {2, 5, 1, 2, 3, 7, 10, 5, 7, 9};
std::cout << "v1 = " << calcWaterStore(v1) << std::endl;
std::vector<int> v2 = {2, 3, 6};
std::cout << "v2 = " << calcWaterStore(v2) << std::endl;
std::vector<int> v3 = {2};
std::cout << "v3 = " << calcWaterStore(v3) << std::endl;
std::vector<int> v4 = {};
std::cout << "v4 = " << calcWaterStore(v4) << std::endl;
std::vector<int> v5 = {8, 5, 6};
std::cout << "v5 = " << calcWaterStore(v5) << std::endl;
std::vector<int> v6 = {8, 5, 1};
std::cout << "v6 = " << calcWaterStore(v6) << std::endl;
std::vector<int> v7 = {8, 5};
std::cout << "v7 = " << calcWaterStore(v7) << std::endl;
std::vector<int> v8 = {8, 8};
std::cout << "v8 = " << calcWaterStore(v8) << std::endl;
std::vector<int> v9 = {2, 3, 6, 5};
std::cout << "v9 = " << calcWaterStore(v9) << std::endl;
std::vector<int> v10 = {2, 3, 6, 4, 10};
std::cout << "v10 = " << calcWaterStore(v10) << std::endl;
std::vector<int> v11 = {2, 3, 6, 4, 6};
std::cout << "v11 = " << calcWaterStore(v11) << std::endl;
std::vector<int> v12 = {2, 3, 6, 2, 5};
std::cout << "v12 = " << calcWaterStore(v12) << std::endl;
std::vector<int> v13 = {2, 5, 1, 2, 3, 7, 10, 5, 7, 9, 7, 14};
std::cout << "v13 = " << calcWaterStore(v13) << std::endl;
return 0;
}