SPOJ WATER : Developing a BFS algorithm - algorithm

I am attempting to solve the following question from SPOJ :
On a rectangular mesh comprising nm fields, nm cuboids were put, one
cuboid on each field. A base of each cuboid covers one field and its
surface equals to one square inch. Cuboids on adjacent fields adhere
one to another so close that there are no gaps between them. A heavy
rain pelted on a construction so that in some areas puddles of water
appeared.
Task
Write a program which:
reads from the standard input a size of the chessboard and heights of cuboids put on the fields
computes maximal water volume, which may gather in puddles after the rain
writes results in the standard output.
Input
The number of test cases t is in the first line of input, then t test
cases follow separated by an empty line. In the first line of each
test case two positive integers 1 <= n <= 100, 1 <= m <= 100 are
written. They are the size of the mesh. In each of the following n
lines there are m integers from the interval [1..10000]; i-th number
in j-th line denotes a height of a cuboid given in inches put on the
field in the i-th column and j-th raw of the chessboard.
Output
Your program should write for each tes case one integer equal to the
maximal volume of water (given in cubic inches), which may gather in
puddles on the construction.
Example
Sample input:
1
3 6
3 3 4 4 4 2
3 1 3 2 1 4
7 3 1 6 4 1
Sample output:
5
I am using a BFS to add how much water will flow from the border elements into the puddle(if theres any path found). But I am unable to handle cases where a puddle maybe like two consecutive cuboids. Can anyone help me with that case?

Here is my answer for the problem. For speaking convenience, I assume the index start from (1,1) to (M,N)
As you can imagine as the flow of water, the water can only travel from the higher cuboid to the lower cuboid ( there is no revert direction i.e. the water from lower cuboid will hit the wall of higher cuboid and stop there).
So we build the graph G = (V,E) such that V are M x N vertices i.e. the cuboid on the matrix. The edge are connected (1-way ONLY) that connected cuboid i(th) to cuboid j(th) when
height(i) >= height(j) and (i and j are physically CONNECTED)
So the problem are just a simple BFS.
By the way, I found another one solve this problem as well. Please take a look
http://www.spojsolutions.com/212-water-among-cubes/

Related

Get all possible paths from one point of a square matrix to another with obstacles

I have a square matrix (say 5x5) with a number of start and end points (say 3 sets):
The ultimate goal is to find the path for each pair of points so that there no path crosses another. In that simple example, there is probably more than one solution, but in real life, once you start adding more pairs of points, there will be a unique solution that fills the entire matrix so that no square is left unoccupied.
My first step however, is to find all possible paths from one start point to its corresponding end point, for each pair of points, so that I can then discard all those where a path crosses another. If possible, I would like to do this without having to resort to graph theory because 1) I know nothing about it and 2) it doesn't appear to be implemented in Octave.
I have done a fair bit of research on that found the following function from GitHub which does almost exactly what I am trying to achieve, but does rely on graph theory:
function pth = pathbetweennodes(adj, src, snk, verbose)
%PATHBETWEENNODES Return all paths between two nodes of a graph
%
% pth = pathbetweennodes(adj, src, snk)
% pth = pathbetweennodes(adj, src, snk, vflag)
%
%
% This function returns all simple paths (i.e. no cycles) between two nodes
% in a graph. Not sure this is the most efficient algorithm, but it seems
% to work quickly for small graphs, and isn't too terrible for graphs with
% ~50 nodes.
%
% Input variables:
%
% adj: adjacency matrix
%
% src: index of starting node
%
% snk: index of target node
%
% vflag: logical scalar for verbose mode. If true, prints paths to
% screen as it traverses them (can be useful for larger,
% time-consuming graphs). [false]
%
% Output variables:
%
% pth: cell array, with each cell holding the indices of a unique path
% of nodes from src to snk.
% Copyright 2014 Kelly Kearney
My problem is trying to compute the adjacency matrix. Not being familiar with graph theory, I kind of understand the concept of an adjacency matrix but am at a loss for actually generating the said matrix.
If I treat each pair separately and consider the other occupied squares as "off-limits", I would have 25 - 4 = 21 nodes for each scenario, and on paper I can write down the edges manually, but I don't know how to code this? Can anybody help?
If we use the example above and order the nodes row-wise, we would have something like this considering the blue pair of points, the goal being to go from node 1 to node 17 (or vice-versa, there is no directionality involved):
1 2 3 4 5
6 7 8
9 10 11 12 13
14 15 16 17
18 19 20 21
The edges are the valid moves (vertical or horizontal, no diagonal) so something like:
1 - 2
2 - 1
2 - 3
2 - 6
3 - 2
3 - 4
etc...
How do you go from this to some code?
Of course, if there is a better way to approach the problem, I'm open to any suggestions. In terms of the scale of the problem, it can go up to a 10x10 grid with 10 pairs of start/end points, so that's 82 nodes.
An adjacency matrix is a matrix for which element adj(n,:) will tell you with booleans (or path lengths) if node n is adjacent to all other elements. e.g. in your case adj(14,:) is all zeroes except for adj(14,9), adj(14,15) and adj(14,18).
You are starting from a good yet slightly off initial though. A node without connections is still a node in your system. That will make your life much easier!
Your initial matrix is simply node_ids=1:25, or if you want node_ids=reshape(1:25,5,5). The nodes that you don't want to visit can be described as nodes that are not adjacent to anything. So, the way to program this is to first create and adjacency matrix for a 5x5 (or whatever size) mesh, and then delete all paths that you do not want, e.g. adj(:,6)=0 (for all nodes, make sure that they are not adjacent to node 6 (note, node is the first red circle in your example)).
To build this matrix you just need to know which nodes are adjacent, but for a cube, finding an equation to give you its adjacents nodes is easy (or just check node_ids(ind2sub(your_node)+[0 1]) and other combinations)

How many ways are there to color uncolored edges in a circle

given n points on a circle and all edges (C(2,n)) are drawn. Some of these edges are already colored in blue or red. You should find out how many ways are possible to color rested edges in order to have final picture with conditions below:
all edges are colored.
all triangles have 0 or 2 edges in red.
here are some examples:
example 1
input: n = 3 and 0 number of edges are already colored.
output = 4 : because we can color all edges in blue or only one one of them in blue and rest of them in red.
example 2
input n = 4 and 4 number of edges are already colored
1 2 blue
2 3 blue
3 4 red
4 1 red
output = 1 : because the only way to color rested edges is like below:
1 3 blue
2 4 red
constraints:
3 <= n <= 100,000
time limit : 1 second
memory limit: 256 MB
actually I have no idea about ideal data structure for such question, and I need your help for some clues
Here's a linear-time algorithm.
First, observe that every cycle of a valid coloring contains an even number of red edges (I'll leave this as an exercise). Given the colors of a spanning tree, there exists exactly one valid completion. Uniqueness is easy to prove because the color of each edge not in the tree is determined by the parity of the colors of the tree edges with which it forms a cycle. I'll leave validity as another exercise (pressed for time, sorry).
The algorithm is, use depth-first search to find a spanning forest of the given edges, storing the parity of the edge colors between each node and the root of its tree. Given this data, we can verify the given color of every edge not in the forest. If any is wrong, then there are 0 colorings. Otherwise, there are 2^(number of trees minus one) colorings.

Two dimensional array scan algorithm

I have being given with a question to scan 2 dimensional array, the array represent a garden, u can step on the garden grass only if the grass is cut down and not too high. a cut down grass represented by number 1. high grass represented with a number bigger then 1, the bigger the number - the higher the grass, heights are unique. in this garden you can have ant colonies which is represented by 0. you can't step on ant colony, no matter what.
Your goal is to cut down all the grass and make it level 1, but u must cat the smallest grass first before you cut any bigger grass. u start from any corner of the garden u choose, as long as u don't stand on an ant colony.
once u cut a grass, it will become number 1, which means, u can now step on it, remember, u can't step on grass bigger then number 1.
Edit:
- heights are unique
The algorithm should return the number of steps made (else -1) , obviously the less steps the better, and you can't go out of the board.
Example:
this matrix
[1,1,1,0]
[1,0,2,1]
[1,0,3,1]
output: 3, because u start from the bottom right cornet, then, u go up, and then left, (chop the grass) and then down (chop grass again).
suggested solution:
is using some kind of a flood fill algorithm (recursion in all directions), and in any case use calculated data structure - like min heap, to hold the current smallest grass height so far, without a pre-clculated min heap we can't never know if we can cut the grass. we take the minimum number from the heap, and start searching for it in the matrix. every cell we encounter, we will go in all directions to search for the number we want.
This solution is obviously the worst, but it solve the problem. I was just wandering if someone can have a better one, I can imagine some dynamic programming solution maybe, not sure. Hell =D
An algorithm that finds the shortest path (with the minimum number of steps):
Collect all cells with height > 1 and sort them by height in increasing order. (They are all unique).
Add the starting cell to the beginning of the sorted collection of cells.
Iterate through the collection and find the shortest path between the current cell and the next cell in the collection, assuming that all cells with higher heights are the ant colonies (cannot be visited). This can be done with BFS. Example:
1 2 4
1 3 0
1 1 1
On the first iteration, we need to find the shortest path between bottom-right corner and cell with height = 2. We should run BFS in the 'virtual garden' where all cells with height > 2 are impossible to go through:
1 2 0
1 0 0
1 1 1
Note, that you need not change higher cells to zero value, just to change the condition in BFS.
Join all found shortest paths.

Given lengths of 3 sides of a triangle, compute an average distance between the middle points of the sides

I have come across a problem. The problem statement is
A team of 3 people, is going to participate in a competition. According to the regulations of this competition, every team is given a single computer, which is located on a triangular table, and three chairs.
Team thinks that the most convenient location of participants is the one where each of the three participants sits at his/her own side of the triangular table, and, what’s important, exactly at the middle of this side. Of course, chairs should be put the same way.
It is important that, during the competition, the participants sit not very far one from another. The Dream Team’s captain thinks that a proper estimation of this factor is an average distance between all the pairs of these participants.
In the case of this competition, one have to compute an average distance between the middle points of the sides of a triangular table. Write a program which computes exactly this. Note that the distance is Euclidean – that is, the distance between (x1,y1) and (x2,y2) is sqrt((x_1 - x_2)^2 + (y_1 - y_2)^2).
Input
The input file contains three positive integer numbers not exceeding 100 – the lengths of sides of the table. It is guaranteed that such a table will have a non-zero area.
Output
Output the average distance between the middle points of the sides of the table, which was described in the input.
Examples
Input Output
3 4 5 2.00000000
5 5 7 2.83333333
I thought of one way to solve this
1. Assume origin as 1 point.
2. If one of the length is 3, assume the point as (3,0).
3. Now, I struck at finding 3rd coordinate
Is my approach, Ok?
Please, give me an algorithm to solve this.
Thank you
Note that segment, connecting middle of edge A and middle of edge B, is half of edge C and the same is true for other sides.
So solution is very simple - average distance for triangle with side lengths A,B,C is
M = (A/2 + B/2 + C/2) / 3 =
(A + B + C ) / 6

Minimum cost path to visit a set of points in a given order exactly once?

The Problem:
We are given a set of N points on a 2D plane, we have to find a path which visits all the points in the order 1-2-3....N and comes back to 1 such that the time taken is minimized. We can move one step to north,east,west or south which takes 1 unit of time. We cannot visit an y of the N points more than once except for 1, which we cannot visit more than twice.
N <= 100
The x and y axis of every point is <= 1000000
(This is the complete problem statement which appeared in a past USACO contest)
My Algorithm:
The x and y axis of the points can be very large but there are just <=100 points so, we change x-axis of the points so that when the are arranged in ascending order of their x axis the difference between the x axis of the adjacent points is 1. We do the same for all the y axis of the points.
Now we find the shortest path from point 1 to 2, from 2 to 3, ... and from N to 1 without visiting any of the given points other than the source and target. We cannot use a straightforward bfs to find the shortest path from, because the distance from a point x,y to a point x+1,y is not 1, but is the original value of x+1 minus the original value of x. So I used Dijktra's algorithm with a binary heap to find the shortest path.
But this algorithm does not work for half of the testcases, it outputs a solution larger than the correct solution.
Why is this algorithm wrong? How do we solve this problem otherwise?
The x and y axis of the points can be very large but there are just <=100 points so, we change x-axis of the points so that when the are arranged in ascending order of their x axis the difference between the x axis of the adjacent points is 1. We do the same for all the y axis of the points.
This essentially means you remove “unused” coordinates. But that will cost you space to maneuver. Take the following example:
4
1 1
3 3
3 2
1 2
The shortest path here takes 8 steps. Assuming positive x is east and positive y is north, that best path would be ennESwWS, with capital letters indicating arrival at the next farm.
/--2
| |
4--|--3
| |
1--/
Now if you do your compression scheme, then you'll remove the y=2 column, and in effect will be left without any column where you could pass from farm 1 to farm 2 without visiting farm 3 or 4. So I see no gain from this compression, but lots of trouble.
So I used Dijktra's algorithm
On what graph? If you use Dijkstra on the farms only, you'll be in trouble, since you have to take the non-farm locations into account. If you take those as well, things should work, as far as I can see. Except for the compression up front.
What you can do if you want to keep this idea is to compress consecutive ranges of empty rows or columns into a single one. That way, your graph will stay reasonably small (201 rows and columns max), but where there is space to manaeuver around farms, your graph will represent that fact.
I guess I'd use a “detour metric” for Dijkstra: every step which brings you closer to the distance has zero cost, while every step that takes you away has cost one. In the end you can take the detour cost, multiply it by two (since every step you take away is also one more step you have to take towards your goal) and add the Manhattan distance of the end points (which is the zero detour cost) and you are back at your original cost. This is basically the idea from A*, but with the performance (and existing implementation) of Disjkstra.
If you compress this
..2
...
3.4
...
1..
to this
.2
34
1.
then you increase the length of the path from 1 to 2 because 34 constitute a spurious obstacle. You could compress multiple empty rows/columns to one empty row/column instead of none.
My thinking is: when is the distance from point i to point i + 1 not the Manhattan Distance? It seems to me that the only scenario for that is when there is a full horizontal or vertical block (or both), e.g.,
(i+1) X (i+1) (i+1)
X
XXX XXXX X XXXX
X X X
i i X i X
I haven't coded anything yet, but perhaps it would be useful to scan for either block when calculating the route to the next point, and calculate the minimal detour if a block exists.

Resources