当时没有写出来,脑子完全懵逼状态。我恨我自己。
求木板中间最大的容水量
其实就一左一右两个指针,保存左高度maxleft,右边高度maxright,如果左的小,就向右移,因为此时右边肯定比左边的大,可以堵住水,如果当前的高度比maxleft小,则有坑,可以计算出此时可以装入的水(maxleft-height[i])。如果比maxleft大,则不能装入水,但要更新maxleft,maxleft和maxright都是保存两边最高的边。
右边也一样。
#include <iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<math.h>
#include<algorithm>
#include <queue>
using namespace std;
int trap(vector<int>& height){
vector<int> dp(height.size());
int l = 0, r = height.size() - 1;
int result = 0;
int ml = 0;
int mr = 0;
while (l < r){
if (height[l] < height[r]){
if (ml < height[l])
ml = height[l];
result += ml;
++l;
}
else{
if (mr < height[r])
mr = height[r];
result += mr;
--r;
}
}
return result;
}
int main(int argc, char* argv[]) {
int T;
cin >> T;
vector<int> result;
while (T--){
int n;
cin >> n;
vector<int> height(n);
for (int i = 0; i < n; ++i){
cin >> height[i];
}
cout << trap(height) << endl;
}
}
注意与下面的题目的差别
就是leetcode011 Trapping Rain Water和LeetCode 407. Trapping Rain Water II
这两种是坑,上面那个木板。就是因为做过这两道题,想在这个基础上面改,没有好好去理解题意,结果还不如重新写。脑子有坑,装得都是水。
leetcode011
#include <iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<math.h>
#include<algorithm>
#include <queue>
using namespace std;
int trap(vector<int>& height){
vector<int> dp(height.size());
int l = 0, r = height.size() - 1;
int result = 0;
int ml = 0;
int mr = 0;
while (l < r){
if (height[l] < height[r]){
if (ml > height[l])
result += (ml - height[l]);
else ml = height[l];
++l;
}
else{
if (mr > height[r])
result += (mr - height[r]);
else mr = height[r];
}
}
return result;
}
int main(int argc, char* argv[]) {
int T;
cin >> T;
vector<int> result;
while (T--){
int n;
cin >> n;
vector<int> height(n);
for (int i = 0; i < n; ++i){
cin >> height[i];
}
cout << trap(height) << endl;
}
}
leetcode407
#include <iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<math.h>
#include<algorithm>
#include <queue>
using namespace std;
//保存地图信息
struct qitem{
int i;
int j;
int h;
qitem(int _i, int _j, int _h):i(_i), j(_j), h(_h){};
};
//从小到大排列
struct cmp{
bool operator()(const qitem& a, const qitem& b){
return a.h > b.h;
}
};
int cal(vector<vector<int>>& heightMap){
priority_queue<qitem, vector<qitem>, cmp> pq;
int rows = heightMap.size();
if (rows <= 1) return 0;
int cols = heightMap[0].size();
//push地图四周的数据
vector<vector<int>> visited(rows, vector<int>(cols, 0));
for (int i = 0; i < rows; ++i){
visited[i][0] = 1;
pq.push( qitem(i, 0, heightMap[i][0]));
visited[i][cols-1] = 1;
pq.push(qitem(i, cols - 1, heightMap[i][cols - 1]));
}
for (int j = 1; j < cols - 1; ++j){
visited[0][j] = 1;
pq.push(qitem(0, j, heightMap[0][j]));
visited[rows - 1][j] = 1;
pq.push(qitem(rows - 1, j, heightMap[rows - 1][j]));
}
///浸水过程 扩展上下左右四个方向
int dx[] = { 0, 0, -1, 1 };
int dy[] = { 1, -1, 0, 0 };
int result = 0;
while (!pq.empty()){
int i = pq.top().i;
int j = pq.top().j;
int h = pq.top().h;
pq.pop();
for (int k = 0; k < 4; ++k){
int tempi = i + dx[k];
int tempj = j + dy[k];
if (tempi > 0 && tempi < rows - 1 && tempj>0 && tempj < cols-1&&visited[tempi][tempj]!=1){
if (heightMap[tempi][tempj] < h){//如果周围有比当前矮的位置,则有坑,加水
result += (h - heightMap[tempi][tempj]);
heightMap[tempi][tempj] = h;//保存为加水后的高度
}
visited[tempi][tempj] = 1;
pq.push(qitem(tempi, tempj, heightMap[tempi][tempj]));
}
}
}
return result;
};
int main(int argc, char* argv[]) {
vector<vector<int>> heightMap = { { 1, 4, 3, 1, 3, 2 }, { 3, 2, 1, 3, 2, 4 }, { 2, 3, 3, 2, 3, 1 } };
//trap(heightMap);
cout << cal(heightMap) << endl;
return 0;
}