# Basic algorithm: calculate how much water can be stored between cylinders

Posted by funkyfela on Wed, 01 Apr 2020 19:10:07 +0200

## Issue In the afternoon, one of the students in the group came up with a simple algorithm problem, which means that there are more than one cubic meter boxes in a room, and multiple boxes can fall vertically together, asking: how many cubic meters of water can be stored in the remaining space (as shown in the figure).

My algorithm is not good all the time, but the brain has to adapt to the following problems.

## Solving problems

In short, we are used to the questions of string, array and linked list. The author hopes to influence the following ideas of the author through a variety of ways. In fact, this problem can be an array problem, that is, the abscissa is used as the index, and the height of the ordinate box is used as the array value, so it can be simply changed into: [0,1,0,4,1,0,1,3...]

According to the barrel theory, it can be known that the influence of water content is determined by the shortest looking board, so the idea is to find the first height and the second height in the array within the specified index interval. The steps of these two indexes are taken as the width and the second height as the height, and then subtract all boxes in the interval to get the final value:

Width * height - occupied box

## Code

``````    private static int sum = 0;

private static List list = new ArrayList();

getSum(0, list.size() - 1);
System.out.println("sum:" + sum);
``````

By recursion, we get the pair high value and the second high value in a given interval, and get the middle area

``````    private static void getSum(int start, int end) {
// Get the first and second highs
int firstIndex = 0;
int firstH = 0;
int secondIndex = 0;
int secondH = 0;

int h = 0;
for (int i = start; i <= end; i++) {
h = Integer.parseInt(list.get(i).toString());
if (h > firstH) {
firstH = h;
firstIndex = i;
}
}

for (int i = start; i <= end; i++) {
if (i == firstIndex) continue;
h = Integer.parseInt(list.get(i).toString());
if (h > secondH) {
secondH = h;
secondIndex = i;
}
}

int left = firstIndex >= secondIndex ? secondIndex : firstIndex;
int right = secondIndex >= firstIndex ? secondIndex : firstIndex;

if (right - left == 1) return;

// Get full area
h = firstH > secondH ? secondH : firstH;
int skip = right - left - 1;
int count = skip * h;

// Delete occupied block
int remove = removeBlock(left + 1, right);

sum += count;
sum -= remove;

if (left - start > 1)
getSum(start, left + 1);
if (end - right > 1)
getSum(right - 1, end);
}
``````

Delete the entity box in the range

``````    private static int removeBlock(int start, int end) {
int remove = 0;
for (int i = start; i < end; i++) {
remove += Integer.parseInt(list.get(i).toString());
}
return remove;
}
``````