How can I get the leftover room space? - arrays

So this is the task I need help with:
The blueprint of a house is made on a unit square grid sheet. All rooms must be rectangular. So far, N rooms have been drawn on the blueprint. Each room is defined by the upper left and lower right corners. One field of the square grid is given by the x and y coordinates, the coordinates of the upper left field (0,0). The x-coordinates increase horizontally and the y-coordinates increase vertically. The designer wants to calculate how many new rectangular rooms can be added if the two sides of any two new rooms cannot have a common part, and all four sides are adjacent or existing, or the side of the house. The rooms planned so far are such that every free space is rectangular. Make a program that tells you what the largest possible new room area can be in your plan.
Input:
The first line of the standard input has the number of rooms in the design (1≤N≤10,000) and the coordinates of the upper left (FX, FY) and lower right (AX, AY) corners of the house (0 ≤ FX < AX ≤ 1000, 0 ≤ FY < AY ≤ 1000), separated by a space. Each of the following N lines has coordinates (FX ≤ LFXi ≤ RAXi ≤ AX, FY ≤ LFYi ≤ RAYi ≤ AY) of the upper left (LFXi, LFYi) and lower right (RAXi, RAYi) of each room, separated by a space.
Output:
The first line of the standard output should be the area of ​​the largest new room!
Theres an example in the link and its the basic input and output that you can test the program with.
I translated this task from hungarian so the Példa=example , Bemenet=input , Kimenet=output. I would be really happy to get some help with this taks because for me it is a little bit too hard.
Basic input example

Related

Find largest square in matrix that can move from one corner to the other

You have a matrix of 0 and 1 for example:
1 1 1 0
1 1 1 0
1 1 1 0
1 1 1 1
0 1 1 1
1 0 1 1
A square is placed at position (0,0), find the size of the largest square of all 1s that be move from the upper left corner to the lower right corner. The square can only move down and to the right and only over elements which are 1.
In this example the size of the largest square is 2. The indexes of elements in the square are (0,0), (0,1), (1,0), (1,1).
I'm not sure how to solve this problem. I think first, you need to find the all the squares in the upper left corner and all squares in lower right corner. If the move is possible, then there must be squares in these 2 positions that are the same size. Then only attempt to move squares in the left corner that are equal in size to square in right corner. But I'm not sure how to go about finding the squares and checking if they can be moved.
You can use dynamic programming.
Let's assume that max_size(i, j) is the size of the largest square that can stay in a (i, j) cell(possibly 0)(stays in means that its top left corner is located in this cell). We can compute this value in a naive way(by iteratively increasing the size of the square and checking that it does not touch any 0). If a naive solution is not feasible, we can use binary search over the answer and prefix sums to get an O(log n) time per cell.
Let's say that f(i, j) is the largest square that can reach the (i, j) cell. The base case: f(0, 0) = max_size(0, 0)(we can always reach the the top left corner). For the other cells, it can be computed in the following way(I omit corner cases here):
for i <- 0 ... n - 1:
for j <- 0 ... m - 1:
f(i, j) = min(max_size(i, j), max(f(i - 1, j), f(i, j - 1)))
The answer is the largest f(i, j) such that i + f(i, j) - 1 = n - 1 and j + f(i, j) - 1 = m - 1.
The time complexity is O(n * m * log(min(n, m))).
Your first step is right: find the largest square that fits into both the lower right and the upper left.
Then, start with a square of that size in the upper left. Try the paths to the lower right breadth-first. After each step, you check whether the square still fits, otherwise reduce its size. You will then often arrive at a given place from two directions (from above and from the left). Continue from there with the bigger size (this unification step is why you should go breadth-first, this is also called "dynamic programming").
In your example, you start with an array of size 2 at (0 0), but let's say that you start with size 3 for demonstration purposes. So, layer 0 is a single square of size 3 at (0 0). Moving down is no problem, but moving to the right steps on some zeroes, so you have to reduce the size. Layer 1 is thus a list of two squares: one of size 3 at (1 0) and one of size 2 at (0 1). Next layer: move right from (0 1), need to reduce to size 1 at (0 2); move down from (0 1) as well as right from (1 0), both arrive at (1 1), from above with size 2, from left needs to reduce to size 2, so size 2; move down from (1 0), reduce to size 2. So, Layer 2 is a list of three squares: one of size 2 at (2 0), one of size 2 at (1 1), and one of size 1 at (0 2). I think this suffices as a demonstration.
You have reached a solution when you complete a layer that contains a square that touches the lower right. You can tell that there is no solution when all your squares are size 0.
Brute force solution
If your matrix has size N x M, every path of a square of size S x S from top left to bottom right is N + M - 2S 'steps' (movements to the right or left) long, where N - S steps will go downwards and M - S steps rightwards. So if we disregard the values on the matrix, there will be (N + M - 2S) choose (N - S) possible paths.
So if the matrix isn't too large, it might be feasible to just try all these paths for a given square size S and test them for compliance with the square placement rules (whether in each step, the square only covers 1s and no 0s.)
Do this for each S from 1 to min(N,M), and keep track of the values of S for which you can find at least one valid path.
Then, just take the maximum of these S values and you've got the wanted result.
So brute-forcing will (eventually) give you the correct value.
Optimizations
Off course, this isn't as efficient as could be, which will lead to enormous runtimes for large matrices. But we can improve step by step, by looking into what steps are unneccesary.
One valid path for a given square size suffices
If you've found a valid path for a given square size S, you don't have to look for more paths for the same square size and can skip to testing other, yet untested square sizes.
One invalid step kills the whole path
If any step of a path leads to an invalid placement, you don't have to check the other steps. You already know you can't use the whole path.
Don't do double work
Each of the (N-S) * (M-S) possible placements of a square with given size S will be part of several paths. Instead of checking each placement's validity for each path it is part of, do it just once for each placement and store the result in a (N-S) x (M-S) matrix.
Bigger won't fit better
If you've tested all paths for a given square size S, and none of them was valid, you don't have to test larger S at all, as you know there won't be valid paths for them.
Smaller won't fit worse
If you've found a path for a given square size S, you can be sure that all smaller square sizes will have at least one valid path, too, so you don't have to test them. (You wouldn't have to, anyway, as you're looking for the maximum S with at least one valid path.)
Bisection?
Combining the two realizations above, you'll come to the conclusion that it won't be optimal to test sizes S in order, be it increasing or decreasing. Rather, you could start somewhere in-between and —depending on the result for that S— rule out all smaller or all larger values for S. Whether it is optimal to start exactly in the middle (at min(N,M) / 2), I'm not sure, though, as the number of paths to search for a given S (remember the binomial coefficient formula in the "Brute force" section above) depends on the size of S.
Parallelization
Almost every level of the brute force algorithm has several steps that are independent of each other and could be executed in parallel.
More?
I'm sure even with all of the above implemented, there's still room for more optimization, even if I can't think of any right now.

How to calculate distance between 2 points in a 2D matrix

I am both new to this website and new to C. I need a program to find the average 'jumps' it takes from all points.
The idea is this: Find "jump" distance from 1 to 2, 1 to 3, 1 to 4 ... 1 to 9, or find 2 to 1, 2 to 3, 2 to 4 2 to 5 etc.
Doing them on the first row is simple, just (2-1) or (3-1) and you get the correct number. But if I want to find the distance between 1 and 4 or 1 to 8 then I have absolutely no idea.
The dimensions of the matrix should potentially be changeable. But I just want help with a 3x3 matrix.
Anyone could show me how to find it?
Jump means vertical or horizontal move from one point to another. from 1 to 2 = 1, from 1 to 9 = 4 (shortest path only)
The definition of "distance" on this kind of problems is always tricky.
Imagine that the points are marks on a field, and you can freely walk all over it. Then, you could take any path from one point to the other. The shortest route then would be a straight line; its length would be the length of the vector that joins the points, which happens to be the difference vector among two points' positions. This length can be computed with the help of Pythagora's theorem: dist = sqrt((x2-x1)^2 + (y2-y1)^2). This is known as the Euclidian distance between the points.
Now imagine that you are in a city, and each point is a building. You can't walk over a building, so the only options are to go either up/down or left/right. Then, the shortest distance is given by the sum of the components of the difference vector; which is the mathematical way of saying that "go down 2 blocks and then one block to the left" means walking 3 blocks' distance: dist = abs(x2-x1) + abs(y2-y1). This is known as the Manhattan distance between the points.
In your problem, however, it looks like the only possible move is to jump to an adjacent point, in a single step, diagonals allowed. Then the problem gets a bit trickier, because the path is very irregular. You need some Graph Theory here, very useful when modeling problems with linked elements, or "nodes". Each point would be a node, connected to their neighbors, and the problem would be to find the shortest path to another given point. If jumps had different weights (for instance, is jumping in diagonal was harder), an easy way to solve this is would be with the Dijkstra's Algorithm; more details on implementation at Wikipedia.
If the cost is always the same, then the problem is reduced to counting the number of jumps in a Breadth-First Search of the destination point from the source.
Let's define the 'jump' distance : "the number of hops required to reach from Point A [Ax,Ay] to Point B [Bx,By]."
Now there can be two ways in which the hops are allowed :
Horizontally/VerticallyIn this case, you can go up/down or left/right. As you have to travel X axis and Y axis independently, your ans is:jumpDistance = abs(Bx - Ax) + abs(By - Ay);
Horizontally/Vertically and also Diagonally
In this case, you can go up/down or left/right and diagonally as well. How it differs from Case 1 is that now you have the ability to change your X axis and Y axis together at the cost of only one jump . Your answer now is:jumpDistance = Max(abs(Bx - Ax),abs(By - Ay));
What is the definition of "jump-distance" ?
If you mean how many jumps a man needs to go from square M to N, if he can only jumps vertically and horizontally, one possibility can:
dist = abs(x2 - x1) + abs(y2 - y1);
For example jump-distance between 1 and 9 is: |3-1|+|3-1| = 4
There are two ways to calculate jump distance.
1) when only horizontal and vertical movements are allowed, in that case all you need to do is form a rectangle in between the two points and calculate the length of two adjacent side. Like if you want to move from 1 to 9 then first move from 1 to 3 and then move from 3 to 9. (Convert it to code)
2) when movements in all eight directions are allowed, things get tricky. Like if you want to move from 1 to 6 suppose. What you'll need to do is you'll have to more from 1 to 5. And then from 5 to 6. The way of doing it in code is to find the maximum in between the difference in x and y coordinates. In this example, in x coordinate, difference is 2 (3-1) and in y coordinate, difference is 1 (2-1). So the maximum of this is 2. So here's the answer. (Convert to code)

How do we find two most-weighted routes in a grid?

We a given a weighted N*N grid W. Two robots r1,r2 start from top left and top right corners respectively. R1 has to reach to the bottom right and R2 the bottom left corners. Here are the valid moves.
R1 moves one square down, R2 moves one square left.
R1 moves one square right, R2 moves one square down.
They must move in such a way that the sum of the weights of the squares they visit (including the starting and ending square) is maximized.
For Examples, if the grid is:
6 0 3 1
7 4 2 4
3 3 2 8
13 10 1 4
In this example, if R1 follows the path marked by * and R2 follows the path marked
by ^, as shown below, their combined score is 56.
6* 0 3^ -1^
7* 4*^ 2^ 4
-3 3*^ -2* 8*
13^ 10^ -1 -4*
It can be verifyed that this is the best combined score that can be achieved for this grid.
We cannot solve this by recursion as N <= 2500 and the time limit is 2 seconds.
If the problem had only one robot, we could solve this by using dynamic programming.
I tried using a similar approach for this problem;
We have two extra N*N grids G1,G2,
for i from 1 to N:
for j from 1 to N and K from N down to 1:
if (G1[i-1][j] + G2[i][k+1]) > (G1[i][j-1] + G2[i-1][k]):
G1[i][j] = G1[i-1][j] + W[i][j]
G2[i][k] = G2[i][k+1] + W[i][k]
else:
G1[i][j] = G1[i][j-1] + W[i][j]
G2[i][k] = G2[i-1][k] + W[i][k]
return G1[N][N] + G2[N][1]
but this gives a wrong answer.
I am not able to understand what is wrong with my algorithm, because for each square it is calculating the max weighted path to rech there.
Can anyone tell me what is wrong with my method and how can i correct it to get the correct answer?
It is a graph problem, and the graph is G=(V,E) where:
V = Squares x Squares (The Cartesian product of all the squares)
(You might want to exclude points where (x1,y1)=(x2,y2), it can be easily done).
E = { all possible ways to move in a turn } = (or formally) =
{ (((x1,y1),(x2,y2)),((x1-1,y1),(x1,y1-1))), (((x1,y1),(x2,y2)),((x1,y1-1),(x1-1,y1))) | per x1,y1,x2,y2 }
Now, once we have the graph - we can see it is actually a DAG - and this is a good thing, because for a general case graph - the longest path problem is NP-Hard, but not for DAG.
Now, given a DAG G, we want to find the longest path from ((0,0),(n,n)) to ((n,n),(0,0)), and it can be done with the following approach:
For simplicity define weight((x1,y1),(x2,y2)) = weight(x1,y1) + weight(x2,y2):
The algorithm:
Use topological sort on the graph
Init D((n,n),(0,0)) = weight((n,n),(0,0)) (the target node)
Iterate the graph according to the sort descending and do for each vertex v:
D(v) = max { D(u) | for each (v,u) in E as described above } + weight(v)
When you are done D((0,0),(n,n)) will have the optimal result.
I could see a typo in the 2nd valid scenario
The valid 2nd scenario should be
R1 moves one square right, R2 moves one square down
but was given as
R2 moves one square right, R2 moves one square down

I need to translate 3d points relative to a triangle as if the triangle was somewhere else

I posted this on twitter a while ago but seeing how none of my followers appears to be a math/programming genius, I'll try my luck here as well. I got here because I found this which might contain part of my solution.
I described my problem in the following pdf document, containing a picture of what I'm trying to achieve.
To give some more details, I divided the pentagon's of a dodecahedron (12 pentagons) into triangles (5/pentagon, 60 triangles in total), then collected a set of data points relative to each of these triangles.
The idea is to generate terrain meshes for each individual triangle.
To do so, the data must be represented flat, in a 32K x 32K square (idTech4 Megatexture)
I have vaguely heard of transformation matrices, which when set up properly, could do the trick of passing all the data points trough them to have them show up in the right place.
I looked at this source code here but I don't understand how I'm supposed to get the points in and/or out of there, not to mention how to do the setup so I can present each point in turn and get the result point back.
I got as fas as identifying the point that belongs in the back right corner. All my 3D points are originally stored in latitude / longitude pairs. I retrieve the 3D vectors this way:
coord getcoord(point* p)
{
coord c;
c.x=cos(p->lat*pi/180.l) * cos(p->lon*pi/180.l);
c.y=cos(p->lat*pi/180.l) * sin(p->lon*pi/180.l);
c.z=sin(p->lat*pi/180.l);
return c;
};
My thought is that if I can find the center of my triangle, and discover how to offset my angles so the vector from the center of my sphere to the middle of the triangle moves to 90N then my points would already be in the right plane if I rotated them all along the same angles. If I then convert them all to 3d and subtracti the radius from y, they'll be at the correct y position as well.
Then all I'd need to do is the rotation, the scaling, and the moving to the final position.
There are several kinds of 'centers' for a triangle, I think the one I need is the one that is equidistant to the corners of the triangle (Circumcenter?)
But then there might be an easier approach to the whole problem so while I continue my own research, perhaps some of you can help pointing me in the right direction.
It appears as if some sample data is in order, here are a few of these triangles in obj file format:
v 0.000000 0.000000 3396.000000
v 2061.582356 0.000000 2698.646733
v 637.063983 1960.681333 2698.646733
f 1 2 3
And another:
v -938.631230 2888.810129 1518.737455
v 637.063983 1960.681333 2698.646733
v 1030.791271 3172.449325 637.064076
f 1 2 3
You will notice that each point is at a distance of 3396 from 0,0,0
I mentioned 'on the sphere' meaning that the face away from the center of the sphere is the face that needs to become the 'top' when translated into the square.
Theoretically all these triangles should in fact have identical sizes, but due to rounding errors in the math that generated them, this might not be entirely true.
If I'm not mistaken I already took measures to ensure that the first point you see here is always the one opposite the longest border, so it's the one that should go in the far left corner (testing the above 2 samples confirms this, but I'm measuring anyway just to be sure)
Both legs leading away from this point should theoretically have the same length as well, but again rounding errors might slightly offset that.
If I've done it correctly then the longer side is 1,113587 times longer than the 2 shorter sides. Assuming those are identical, then doing some goal seeking in excel, I can deduct that the final points, assuming I was just translating this triangle, should look like:
v 16384.000000 0.000000 16384.000000
v -16384.000000 0.000000 9916.165306
v 9916.165306 0.000000 -16384.000000
f 1 2 3
So I need to setup the matrix to do this transformation, preferably using the 4x4 matrix as explained below.
I would recommend using transform matrices. The 3d transform matrix is a 4x4 data structure which describes a translation and rotation (and possibly a scale). Once you have a matrix you can transform a point like so
result.x = (tmp->pt.x * m->element[0][0]) +
(tmp->pt.y * m->element[1][0]) +
(tmp->pt.z * m->element[2][0]) +
m->element[3][0];
result.y = (tmp->pt.x * m->element[0][1]) +
(tmp->pt.y * m->element[1][1]) +
(tmp->pt.z * m->element[2][1]) +
m->element[3][1];
result.z = (tmp->pt.x * m->element[0][2]) +
(tmp->pt.y * m->element[1][2]) +
(tmp->pt.z * m->element[2][2]) +
m->element[3][2];
int w = (tmp->pt.x * m->element[0][3]) + (tmp->pt.y * m->element[1][3])
+ (tmp->pt.z * m->element[2][3]) + m->element[3][3];
if (w!=0 || w!=1)
result.x/=w; result.y/=w; result.z/=w;
This will transform the 3D point pt by the matrix m. If you now a little matrix math you'll see i'm just multiplying my origin point as a vector against the matrix (and doing a little normalization if it is a skew matrix.) Matrices can be multiplied together to form complicated transformations so they are very useful.
For details on making matrices suggest reading this link.
http://en.wikipedia.org/wiki/Transformation_matrix

Dividing circle into pieces by choosing points on circumference?

On a circle, N arbitrary points are chosen on its circumference. The complete graph formed with those N points would divide the area of the circle into many pieces.
What is the maximum number of pieces of area that the circle will get divided into when the points are chosen along its circumference?
Examples:
2 points => 2 pieces
4 points => 8 pieces
Any ideas how to go about this?
This is known as Moser's circle problem.
The solution is:
i.e.
The proof is quite simple:
Consider each intersection inside the circle. It must be defined by the intersection of two lines, and each line has two points, so every intersection inside the circle defines 4 unique sets of points on the circumference. Therefore, there are at most n choose 4 inner vertices, and obviously there are n vertices on the circumference.
Now, how many edges does each vertex touch? Well, it's a complete graph, so each vertex on the outside touches n - 1 edges, and of course each vertex on the inside touches 4 edges. So the number of edges is given by (n(n - 1) + 4(n choose 4))/2 (we divide by two because otherwise each edge would be counted twice by its two vertices).
The final step is to use Euler's formula for the number of faces in a graph, i.e.: v - e + f = 1 (the Euler characteristic is 1 in our case).
Solving for f gives the formulae above :-)

Resources