# Program to Find Out the Amount of Rain to be Caught between the Valleys in C++

Suppose we have a 2D matrix, where the elements represent the height of a terrain. Let's imagine a situation where it will rain and all the spaces in the valleys get filled up.

We have to find out the amount of rain that will be caught between the valleys.

So, if the input is like

 6 6 6 8 6 4 5 8 6 6 6 6

then the output will be 3 as we can hold 3 units of water in between 4 and 5 squares.

To solve this, we will follow these steps −

• Define a structure Data, that contains x and y coordinate and height h

• Define a priority queue pq, it stores data items sorted on height values

• n := size of h

• if n is non-zero, then −

• return 0

• m := size of h[0]

• Define one set of pairs called visited

• for initialize i := 0, when i < n, update (increase i by 1), do −

• insert new Data(h[i, 0], i, 0) into pq

• insert {i, 0} into visited

• insert new Data(h[i, m - 1], i, m - 1) into pq

• insert {i, m - 1} into visited

• for initialize i := 1, when i < m - 1, update (increase i by 1), do −

• insert new Data(h[0, i], 0, i) into pq

• insert {0, i} into visited

• insert new Data(h[n - 1, i], n - 1, i) into pq

• insert {n - 1, i} into visited

• ret := 0

• maxVal := 0

• while pq is not empty, do −

• temp = top element of pq

• delete top element from pq

• maxVal := maximum of height of temp and maxVal

• x := x of temp

• y := y of temp

• for initialize i := 0, when i < 4, update (increase i by 1), do −

• nx := x + dir[i, 0]

• ny := y + dir[i, 1]

• if nx >= 0 and ny >= 0 and nx < n and ny < m and {nx, ny} is not visited, then −

• val := h[nx, ny]

• if val < maxVal, then −

• ret := ret + maxVal - val

• val := maxVal

• insert new Data(val, nx, ny) into pq

• insert {nx, ny} into visited

• return ret

## Example

Let us see the following implementation to get better understanding −

Live Demo

#include <bits/stdc++.h>
using namespace std;
struct Data {
int x, y;
int h;
Data(int a, int b, int c) {
h = a;
x = b;
y = c;
}
};
struct Comparator {
bool operator()(Data a, Data b) {
return !(a.h < b.h);
}
};
int dir[4][2] = {{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
class Solution {
public:
int solve(vector<vector<int>>& h) {
priority_queue<Data, vector<Data>, Comparator> pq;
int n = h.size();
if (!n)
return 0;
int m = h[0].size();
set<pair<int, int>> visited;
for (int i = 0; i < n; i++) {
pq.push(Data(h[i][0], i, 0));
visited.insert({i, 0});
pq.push(Data(h[i][m - 1], i, m - 1));
visited.insert({i, m - 1});
}
for (int i = 1; i < m - 1; i++) {
pq.push(Data(h[0][i], 0, i));
visited.insert({0, i});
pq.push(Data(h[n - 1][i], n - 1, i));
visited.insert({n - 1, i});
}
int ret = 0;
int maxVal = 0;
while (!pq.empty()) {
Data temp = pq.top();
pq.pop();
maxVal = max(temp.h, maxVal);
int x = temp.x;
int y = temp.y;
int nx, ny;
for (int i = 0; i < 4; i++) {
nx = x + dir[i][0];
ny = y + dir[i][1];
if (nx >= 0 && ny >= 0 && nx < n && ny < m && !visited.count({nx, ny})) {
int val = h[nx][ny];
if (val < maxVal) {
ret += maxVal - val;
val = maxVal;
}
pq.push(Data(val, nx, ny));
visited.insert({nx, ny});
}
}
}
return ret;
}
};
int solve(vector<vector<int>>& matrix) {
return (new Solution())->solve(matrix);
}
int main(){
vector<vector<int>> v = {
{6, 6, 6, 8},
{6, 4, 5, 8},
{6, 6, 6, 6}
};
cout << solve(v);
}

## Input

{
{6, 6, 6, 8},
{6, 4, 5, 8},
{6, 6, 6, 6}
};

## Output

3

Updated on: 23-Dec-2020

48 Views

##### Kickstart Your Career

Get certified by completing the course