当青训营遇上码上掘金
1.题意分析
1.1简单模型 只有两面墙构成的水池
其接水量是两面墙体中最矮的决定的,结果是水池宽度乘以矮墙高度。
1.2真实情形
与模型的联系:真正的水池完全可以看成是许多墙体彼此依靠共用其边来创造的N多水池。
与模型的区别:各个小水池的双边高度不好获取,若是依次按照水池获得左右双边的高度一定效率低下。
进一步思考后:由于每个小水池都有与其它小水池公用的边,若能将每个小水池的边仅获取一遍,就能解决效率问题。
最后的方案是:(双指针) 将整个水池看成一个水池,得到其左右墙的高度,比较高度,从矮墙一侧开始记录水量,直到遇到比矮墙高的墙就停下,再次得到现在的左右墙,再次记录水量。直到左右墙合并了(边界条件)。
进行一定的论证:对于整个水池和他的左右墙,其水量一定不小于 水池宽度乘以矮墙高度 ,若其中不存在比矮墙高的墙,则水量计算公式没有问题,若其中存在比矮墙高的墙,则将已经计算的部分划为一个小水池,将未计算的部分再次视作一个水池则能计算完成。
注意:边界条件要分析清楚
2.代码
//青训营 X 码上掘金 主题4 code
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> height;
int t;
while (cin >> t)
height.push_back(t);
int leftPointer = 0;
int rightPointer = height.size() - 1;
int leftWall = height[leftPointer];
int rightWall = height[rightPointer];
int sum = 0;
// 获得第一道左墙
while (leftWall == 0)
{
leftPointer++;
// 超界
if (leftPointer >= height.size())
break;
leftWall = height[leftPointer];
}
// 获得第一道右墙
while (rightWall == 0)
{
rightPointer--;
// 超界
if (rightPointer < 0)
break;
rightWall = height[rightPointer];
}
while (rightPointer > leftPointer)
{
// 从矮墙开始接豆
if (leftWall < rightWall)
{
while (leftWall >= height[leftPointer])
{
// 接完豆了
if (rightPointer == leftPointer)
break;
sum += leftWall - height[leftPointer];
leftPointer++;
}
leftWall = height[leftPointer];
}
else
{
while (rightWall >= height[rightPointer])
{
// 接完豆了
if (rightPointer == leftPointer)
break;
sum += rightWall - height[rightPointer];
rightPointer--;
}
rightWall = height[rightPointer];
}
}
cout << sum;
}