Description:
Given matrix [x] [y], with x- rows and y- number of columns . Filled random numbers from 0 to 5 inclusive .
Description of finding a solution : the solution is considered to be a set of matrix elements that are adjacent to each other ( diagonal neighborhood is not taken into account ) and the sum of the number are 10. Each element of the matrix can be used 1 time for a decision . The solution may have any number of digits. The decision must end any number other than zero .
Example:
given
0 1 2 3 4 5
1 2 3 4 5 0
2 3 4 5 1 2
Solution 1 : (1 - 2 - 3 - 4)
0 **1** 2 3 4 5
1 **2** 3 4 5 0
2 **3** **4** 5 1 2
i tried to do smth like this, but it is wrong, i dont know when i must stop,
Solution it is a class which contains mair of indexes, pls help me.
void xxx(int colCount, int rowCount, int currentRow, int currentCol, int** matrix, int sum, Solution *solution, int solCount) {
sum += matrix[currentRow][currentCol];
matrix[currentRow][currentCol] = -1;
if(sum > 10){
sum - = matrix[currentRow][currentCol];
return;
} else if(sum == 10){
solution[solCount].additem(currentRow, currentCol);
return xxx(5,5,currentRow - 1, currentCol, matrix, sum, solution, solCount+1);
} else {
//UP
if( currentRow > 0 && matrix [currentRow - 1][currentCol] != -1){
xxx(5,5,currentRow - 1, currentCol, matrix, sum, solution,solCount);
}
//LEFT
if(currentCol > 0 && matrix [currentRow][currentCol-1] != -1){
xxx(5,5,currentRow, currentCol - 1, matrix, sum, solution,solCount);
}
//DOWN
if(currentRow + 1 < colCount && matrix[currentRow + 1][currentCol] != -1){
xxx(5,5,currentRow + 1, currentCol, matrix, sum, solution,solCount);
}
//RIGHT
if(currentCol + 1 < rowCount && matrix[currentRow][currentCol + 1] != -1){
xxx(5,5,currentRow, currentCol + 1, matrix, sum, solution,solCount);
}
}
}
Related
I represent a n*m matrix like chessboard.
1 0 2 0
0 3 0 4
5 0 6 0
0 7 0 8
I don't need to store the zeros in my 1d vector.
vector v = {1, 2, 3, 4.. etc}
I ask the user for a row and column number.
How can i return with i. row j. column element?
if (i+j) % 2 != 0
I return with 0, but i don't know what i need to do when
(i+j) % 2 == 0
Can you help me? (sorry for my bad English)
With regular matrices stored as 1D-vector, coordinate to index would be:
(i + j * width) (or i * height + j depending on convention).
with half case to 0, you just have to divide by 2:
if ((i + j) % 2 != 0) return 0;
else return data[(i + j * width) / 2];
I have two dimensional array of chars, where all numbers, excluding one * (as given in picture (two examples)
My task is to sum up all neighbour integers ( in example 1, neighbours of * are 4,2,5,8 and sum is 4+2+5+8=19)
But in example 2, * doesn't have top neighbour.
My initial code was like:
arr[i-1][j] + arr[i+1][j] + arr[i][j-1] + arr[i][j+1]
But then I understood that in case like a[0][-1] doesn't exist. So can you help me to to solve my problem
You need to explicitly check each one. The following should work:
bool inRange(int i, int j) {
const auto n = 4; // you need to set this somewhere, or pass it in
return (i >= 0) && (i < n) && (j >= 0) && (j < n);
}
auto sum = (inRange(i-1, j) ? arr[i-1][j] : 0)
+ (inRange(i+1, j) ? arr[i+1][j] : 0)
+ (inRange(i, j-1) ? arr[i][j-1] : 0)
+ (inRange(i, j+1) ? arr[i][j+1] : 0);
You can probably write this a little cleaner, but you need to check not only for the -1, but also for when you go over 3.
There can be multiple solutions to this problem, but if you want to avoid checking bound each time you can extend the matrix dimension by 1 than needed. That means if you have an array:
1 * 4 7
8 9 2 3
5 1 2 4
4 3 6 5
Implement it as:
0 0 0 0 0 0
0 1 * 4 7 0
0 8 9 2 3 0
0 5 1 2 4 0
0 4 3 6 5 0
0 0 0 0 0 0
Doing this won't even affect your sum at the end.
I am fairly new to C++, and am struggling through a problem that seems to have a solid solution but I just can't seem to find it. I have a contiguous array of ints starting at zero:
int i[6] = { 0, 1, 2, 3, 4, 5 }; // this is actually from an iterator
I would like to partition the array into groups of three. The design is to have two methods, j and k, such that given an i they will return the other two elements from the same group of three. For example:
i j(i) k(i)
0 1 2
1 0 2
2 0 1
3 4 5
4 3 5
5 3 4
The solution seems to involve summing the i with its value mod three and either plus or minus one, but I can't quite seem to work out the logic.
This should work:
int d = i % 3;
int j = i - d + ( d == 0 );
int k = i - d + 2 - ( d == 2 );
or following statement for k could be more readable:
int k = i - d + ( d == 2 ? 1 : 2 );
This should do it:
int j(int i)
{
int div = i / 3;
if (i%3 != 0)
return 3*div;
else
return 3*div+1;
}
int k(int i)
{
int div = i / 3;
if (i%3 != 2)
return 3*div+2;
else
return 3*div+1;
}
Test.
If you want shorter functions:
int j(int i)
{
return i/3*3 + (i%3 ? 0 : 1);
}
int k(int i)
{
return i/3*3 + (i%3-2 ? 2 : 1);
}
Well, first, notice that
j(i) == j(3+i) == j(6+i) == j(9+i) == ...
k(i) == k(3+i) == k(6+i) == k(9+i) == ...
In other words, you only need to find a formula for
j(i), i = 0, 1, 2
k(i), i = 0, 1, 2
and then for the rest of the cases simply plug in i mod 3.
From there, you'll have trouble finding a simple formula because your "rotation" isn't standard. Instead of
i j(i) k(i)
0 1 2
1 2 0
2 0 1
for which the formula would have been
j(i) = (i + 1) % 3
k(i) = (i + 2) % 3
you have
i j(i) k(i)
0 1 2
1 0 1
2 0 2
for which the only formula I can think of at the moment is
j(i) = (i == 0 ? 1 : 0)
k(i) = (i == 1 ? 1 : 2)
If the values of your array (let's call it arr, not i in order to avoid confusion with the index i) do not coincide with their respective index, you have to perform a reverse lookup to figure out their index first. I propose using an std::map<int,size_t> or an std::unordered_map<int,size_t>.
That structure reflects the inverse of arr and you can extra the index for a particular value with its subscript operator or the at member function. From then, you can operate purely on the indices, and use modulo (%) to access the previous and the next element as suggested in the other answers.
I have a big matrix as input, and I have the size of a smaller matrix. I have to compute the sum of all possible smaller matrices which can be formed out of the bigger matrix.
Example.
Input matrix size: 4 × 4
Matrix:
1 2 3 4
5 6 7 8
9 9 0 0
0 0 9 9
Input smaller matrix size: 3 × 3 (not necessarily a square)
Smaller matrices possible:
1 2 3
5 6 7
9 9 0
5 6 7
9 9 0
0 0 9
2 3 4
6 7 8
9 0 0
6 7 8
9 0 0
0 9 9
Their sum, final output
14 18 22
29 22 15
18 18 18
I did this:
int** matrix_sum(int **M, int n, int r, int c)
{
int **res = new int*[r];
for(int i=0 ; i<r ; i++) {
res[i] = new int[c];
memset(res[i], 0, sizeof(int)*c);
}
for(int i=0 ; i<=n-r ; i++)
for(int j=0 ; j<=n-c ; j++)
for(int k=i ; k<i+r ; k++)
for(int l=j ; l<j+c ; l++)
res[k-i][l-j] += M[k][l];
return res;
}
I guess this is too slow, can anyone please suggest a faster way?
Your current algorithm is O((m - p) * (n - q) * p * q). The worst case is when p = m / 2 and q = n / 2.
The algorithm I'm going to describe will be O(m * n + p * q), which will be O(m * n) regardless of p and q.
The algorithm consists of 2 steps.
Let the input matrix A's size be m x n and the size of the window matrix being p x q.
First, you will create a precomputed matrix B of the same size as the input matrix. Each element of the precomputed matrix B contains the sum of all the elements in the sub-matrix, whose top-left element is at coordinate (1, 1) of the original matrix, and the bottom-right element is at the same coordinate as the element that we are computing.
B[i, j] = Sum[k = 1..i, l = 1..j]( A[k, l] ) for all 1 <= i <= m, 1 <= j <= n
This can be done in O(m * n), by using this relation to compute each element in O(1):
B[i, j] = B[i - 1, j] + Sum[k = 1..j-1]( A[i, k] ) + A[j] for all 2 <= i <= m, 1 <= j <= n
B[i - 1, j], which is everything of the sub-matrix we are computing except the current row, has been computed previously. You keep a prefix sum of the current row, so that you can use it to quickly compute the sum of the current row.
This is another way to compute B[i, j] in O(1), using the property of the 2D prefix sum:
B[i, j] = B[i - 1, j] + B[i, j - 1] - B[i - 1, j - 1] + A[j] for all 1 <= i <= m, 1 <= j <= n and invalid entry = 0
Then, the second step is to compute the result matrix S whose size is p x q. If you make some observation, S[i, j] is the sum of all elements in the matrix size (m - p + 1) * (n - q + 1), whose top-left coordinate is (i, j) and bottom-right is (i + m - p + 1, j + n - q + 1).
Using the precomputed matrix B, you can compute the sum of any sub-matrix in O(1). Apply this to compute the result matrix S:
SubMatrixSum(top-left = (x1, y1), bottom-right = (x2, y2))
= B[x2, y2] - B[x1 - 1, y2] - B[x2, y1 - 1] + B[x1 - 1, y1 - 1]
Therefore, the complexity of the second step will be O(p * q).
The final complexity is as mentioned above, O(m * n), since p <= m and q <= n.
Do you know some algorithm(better than brute-force) which can find vertex in the graph that are separated by one vertex and aren't connected between each other. Example:
In this graph found paths would be:
1 - 4
2 - 4
3 - 5
The best would be c++ code which uses array of stl lists as a graph representation but code in any other procedural language or pseudocode would also be fine.
One way would be based on a breadth-first-style search, where for each vertex i in the graph, we scan the vertices adjacent to those adjacent to i (i.e. two levels of adjacency!).
mark = array[0..n-1] of 0
flag = 1
for i = nodes in graph do
// mark pattern of nodes adjacent to i
mark[i] = flag
for j = nodes adjacent to i do
mark[j] = flag
endfor
// scan nodes adjacent to those adjacent to i
// (separated by one vertex!)
for j = nodes adjacent to i do
for k = nodes adjacent to j do
if mark[k] != flag and k > i then
// i,k are separated by another vertex
// and there is no edge i,k
// prevent duplicates
mark[k] = flag
endif
endfor
endfor
// implicit unmarking of current pattern
flag += 1
endfor
If the graph had m edges per vertex, this would be an O(n * m^2) algorithm that requires O(n) extra space.
One simple and intuitive solution to this problem lies in the adjacency matrix. As we know, (i,j) th element of the nth power of an adjacency matrix lists all the paths of length exactly n between i and j.
So i just read in A, the adjacency matrix and then calculate A^2. Finally, i list all the pairs which have exactly one path of length 2 between them.
//sg
#include<stdio.h>
#define MAX_NODE 10
int main()
{
int a[MAX_NODE][MAX_NODE],c[MAX_NODE][MAX_NODE];
int i,j,k,n;
printf("Enter the number of nodes : ");
scanf("%d",&n);
for(i=0;i<n;i++)
for(j=0;j<=i;j++)
{
printf("Edge from %d to %d (1 yes/0 no) ? : ",i+1,j+1);
scanf("%d",&a[i][j]);
a[j][i]=a[i][j]; //undirected graph
}
//dump the graph
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
c[i][j]=0;
printf("%d",a[i][j]);
}
printf("\n");
}
printf("\n");
//multiply
for(i=0;i<n;i++)
for(j=0;j<n;j++)
for(k=0;k<n;k++)
{
c[i][j]+=a[i][k]*a[k][j];
}
//result of the multiplication
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("%d",c[i][j]);
}
printf("\n");
}
for(i=0;i<n;i++)
for(j=0;j<=i;j++)
{
if(c[i][j]==1&&(!a[i][j])&&(i!=j)) //list the paths
{
printf("\n%d - %d",i+1, j+1 );
}
}
return 0;
}
Sample Run For Your Graph
[aman#aman c]$ ./Adjacency2
Enter the number of nodes : 5
Edge from 1 to 1 (1 yes/0 no) ? : 0
Edge from 2 to 1 (1 yes/0 no) ? : 1
Edge from 2 to 2 (1 yes/0 no) ? : 0
Edge from 3 to 1 (1 yes/0 no) ? : 1
Edge from 3 to 2 (1 yes/0 no) ? : 1
Edge from 3 to 3 (1 yes/0 no) ? : 0
Edge from 4 to 1 (1 yes/0 no) ? : 0
Edge from 4 to 2 (1 yes/0 no) ? : 0
Edge from 4 to 3 (1 yes/0 no) ? : 1
Edge from 4 to 4 (1 yes/0 no) ? : 0
Edge from 5 to 1 (1 yes/0 no) ? : 0
Edge from 5 to 2 (1 yes/0 no) ? : 0
Edge from 5 to 3 (1 yes/0 no) ? : 0
Edge from 5 to 4 (1 yes/0 no) ? : 1
Edge from 5 to 5 (1 yes/0 no) ? : 0
01100
10100
11010
00101
00010
21110
12110
11301
11020
00101
4 - 1
4 - 2
5 - 3
Analysis
For n vertices :
Time : O(n^3) . Can be reduced to O(n^2.32), which is very good.
Space : O(n^2).
You can do this with a adapted version of Warshall's algorithm. The algorithm in the following code example uses the adjacency matrix of your graph and prints i j if there
is a edge from i to k and a edge from k to j but no direct way from i to j.
#include <iostream>
int main() {
// Adjacency Matrix of your graph
const int n = 5;
bool d[n][n] = {
{ 0, 1, 1, 0, 0 },
{ 0, 0, 1, 0, 0 },
{ 0, 0, 0, 1, 0 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0 },
};
// Modified Warshall Algorithm
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
if (d[i][k])
for (int j = 0; j < n; j++)
if (d[k][j] && !d[i][j])
std::cout << i + 1 << " " j + 1 << std::endl;
}
You can view the result online.