Two dimensional array scan algorithm - 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.

Related

Recursively compute closest pairs

I am trying to perform the closest pairs algorithm - there is one area however where I am totally stuck.
The problem can be solved in O(n log n) time using the recursive divide and conquer approach, e.g., as follows:
1) Sort points according to their x-coordinates.
2) Split the set of points into two equal-sized subsets by a vertical line x=xmid.
3) Solve the problem recursively in the left and right subsets. This yields the left-side and right-side minimum distances dLmin and dRmin, respectively.
4) Find the minimal distance dLRmin among the set of pairs of points in which one point lies on the left of the dividing vertical and the second point lies to the right.
5) The final answer is the minimum among dLmin, dRmin, and dLRmin.
My problem is with Step 3: Let's say that you've split your 8 element array into two halves, and on the left half you have 4 points - 1,2,3 and 4. Let's also say that points 2 and 3 are the closest pair among those 4 points. Well, if you keep recursively dividing this subset into halves, you will eventually end up calculating the min between 1-2 (on the left), you will calculate the min between 3-4 (on the right), and you will return the minimum-distance pair from those two pairs..
HOWEVER - you've totally missed the distance between 2-3, as you've never calculated it since they were on opposite sides... so how is this issue solved? Notice how Step 4 comes AFTER this recursive process, it seems to be an independent step and only applies to the end result after Step 3, and not to every subsequent division of the subarrays that occurs within Step 3.. is it? Or is there another way of doing this that I'm missing?
The steps are a bit misleading, in that steps 2-5 are all part of the recursion. At every level of recursion, you need to calculate dLmin, dRmin, and dLRmin. The minimum of these is returned as the answer for that level of recursion.
To use your example, you would calculated dLmin as the distance between points 1 and 2, dRmin as the distance between points 3 and 4, and then dLRmin as the distance between points 2 and 3. Since dLRmin is the smallest in your hypothetical case, it would be returned.

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.

Split the set of points, algorithm

I'm learning for the test and I can't manage with this problem:
We are given a set of n < 1000 points and an integer d. The task is to create two disjoint sets of points A_1 and A_2 (which union is given set of n points) in such way that the distance (euclidean) between each pair of points from A_i (for i = 1 or 2) is less or equal to d. If it is not possible, print -1.
For example, input:
d = 3, and points:
(5,3), (1,1), (4,2), (1,3), (5,2), (2,3), (5,1)
we can create:
A_1 = { (2,3), (1,3), (1,1) }
A_2 = { (5,3), (4,2), (5,2), (5,1) }
since each pair of points from A_i (for i = 1 or 2) are close enough.
I really want to know how to solve it, but no idea. Since n is small, algorithm can be even O(n^2 log n), but I don't know how to start. I was thinking that maybe start with counting the distance between each pair of points, then take two points with maximum distance and place them in to different sets (if their distance is greater than d). Then repeat this step for the rest of pairs, but the problem is how to decide where I can legally put next points. Can anyone help with this algorithm?
Let's consider a simple graph with n nodes (corresponding to the n points). Two nodes are connected if the distance between the two corresponding points is greater that d.
If is is possible to create the two disjoints sets, we must have a bi-partite graphe (if some nodes are not connected to the others, they can be put in any set).
Thus, we only need to test the bipartiteness of the graph which is simple :
http://en.wikipedia.org/wiki/Bipartite_graph#Testing_bipartiteness
Think of an array with all the points across the top and all the points down the side.
Fill in the array with a zero in any cell if the two points (left and top) that define the cell are more than d apart and one if the two points are less than d apart.
(5,3), (1,1), (4,2), (1,3), (5,2), (2,3), (5,1)
(5,3), 0 1 0 1 1 1
(1,1), 0 0 1 0 1 0
(4,2), 1 0 0 1 1 1
(1,3), 0 1 0 0 1 0
(5,2), 1 0 1 0 0 1
(2,3), 1 1 1 1 0 0
(5,1) 1 0 1 0 1 0
(Note: You have to fill in the each triangle with the same 0s and 1s flipped.)
Ignore the diagonal. Pay attention to the top-right triangular section.
Skip the 0th column.
Start with the 1st column and, if it doesn't have a 1 in the top row, swap it with another column to its right that has a 1 in the top row. Then swap the same rows too to keep the diagonal blank. (If there isn't one, there is no solution.) [Example: Swap column 2 and 3 and row 2 and 3] Note that the choice of this row may become an optimizing factor.
Move to the next column and if it doesn't have a 1 in the top row, swap with a column to the right that does and swap the corresponding rows. If there is not one, try swapping it with a row below it that has a 1 in that column and do the corresponding column. The rows below it should be ignored if below the diagonal.
We are collecting points in the top left corner of the triangle that have 1's in them. These points can all go in one of the collections.
This is where I get lost in doing this in my head but you have to do a similar process starting in the bottom right corner of the triangle and collecting points that will be in the other collection. Swap rows and corresponding columns to collect 1s in the bottom right corner of the triangle.
Once you have swapped enough rows that you can form a rectangle in the top right corner--a true rectangle without the bottom left corner cut off--and that rectangle contains all the 0's, you have a solution. If you can't do that, there is no solution.
There is a comparison of the lowest row with a 1 in the triangle and the rightmost column with a 1 in the triangle and the cell where they meet. That cell has to be in the triangle for a solution to exist.
(I left you a big "to-do" to find how to interleave the swaps of rows and columns to clean the 0's out of the top-left and bottom-right corners of the triangle. Maybe a discussion here can resolve how to make it work. Or find out it won't work.)
Starting with a distance matrix seems to be a good idea. Then in this distance matrix pick every entry that is greater than d. This entry means that the according points have to be in different sets.
Start with two empty sets and iterate all relevant entries ( > d).
If sets are empty, put the two points into them. Otherwise there are three options:
If it is clear which set the points belong to, put them into them (that means, inserting the point preserves the max-distance criterion, which can be obtained from the distance matrix).
If the points cannot be inserted into one of the sets, the problem is not solvable.
If both sets are possible for both points, we have a problem. I would suggest starting a new pair of point sets and putting the points into them. Then if a subsequent point pair is unclear again, check for the second set pair. If it is yet unclear, check for a third set pair and so on. If a point pair is inserted into a previous set, check the following sets, if points are now clear. At the end you have a list of pairs of sets of points, which can be united as you wish.
I just had an idea for a second approach, which is similar, but should be a bit faster.
We also start with the distance matrix.
Additional to the two sets, we maintain a stack, queue or whatever of newly added entries.
So if we pick the first relevant entry from the distance matrix, the points are added to both queues. As long as there is an entry in one of the queues, do the following:
Remove the point from the queue and insert it into the set. If the insertion breaks the max-distance criterion, the problem is not solvable. Examine the row or column in the distance matrix for this very point and extract every relevant entry in this row/column. Add the partner point to the queue of the other set (because this has to be in a different set).
If both queues are empty, add the next relevant entry that has not yet been visited to the queues and start over.
This algorithm has the advantage that the points are processed in the order they can impact each other. Therefore, there is no need for more than one pair of sets.

Given a NxN matrix, how could I find all possible paths to a location (i,i)?

Given a NxN matrix, how could I find all possible paths to a location (i,i). Navigation would be only downwards and towards the right. The starting point would be (0,0).
P.S. Not a homework.
The easiest (for me) would be to do it recursively:
1) the stop condition would be arriving at (i,i)
2) you would try two next moves at each recursion level:
can you go down
can you go right
Assuming that your current position is (x,y):
You cannot go right if your current "y" plus 1 would be bigger than "i" in the (i,i).
You cannot go down if your current "x" plus 1 would be bigger than "i" in the (i,i).
You'd just have to remember the path in some variable or pass it downwards and print it when the stop condition occurs.
So assuming you start at (0,0) you remember this and then check if you can go right or down, if yes for both then you recursively call this same method for (0,1) and (1,0).
?
To a location (i, i), i.e. one on the diagonal, there are exactly comb(i, 2 * i) paths (number of ways to select i elements from a set of 2 * i elements), each consisting of i movements rightward and i movements downward. Enumerating them is trivial.
Although you can use DP to solve this, this is just simle math:
You have to make 2i steps, from which i must be steps to the right. The total combinations are C(2i,i). See: computing the binomial coefficients.
Another similar problem is where you cannot cross the diagonal, called monotonic path, for which the interesting Catalan number sequence is the solution.
Look at the problem from a 45 degree angle. You'll see that you're trying to calculate the number of paths to a vertex on a triangular array. The solution is given by Pascal's triangle.
2i choose i
Solution 1 - Using dynamic programming :
Add up the solutions bottom up till (i,j) indices you want:
ans(i,i) = ans(i-1,j) + ans(i,j-1)
and use the same for position (i,i).
Solution 2 - Using simple permutation and combination
ans = (2i)!/ i!i!
(Since you have to choose any of the i steps towards the right and ji steps downwards starting from (0,0) and total are 2i steps).
It depends when you start from (0,0) or at a random location in the matrix.
If it is (0,0) ; use Depth First to go until the end of one branch then the others. Use Breadth First to iterate through all neigbouring nodes at a step.
Check only down and right nodes.
If it is at a random location in the matrix, you need to trace all 4 neighbouring nodes.

SPOJ WATER : Developing a BFS 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/

Resources