algorithm transfer one coin matrix to another coin matrix - c++

Description:
There are m * n (m <= 100, n <=100) coins on the desktop forming a m row n column coin matrix. Every coin either face upward, or face backward, represented by 0 or 1.
Rules of the game are:
(1) every time, you are allowed to inverse one row of coins.
(2) every time, you are allowed to swap two columns.
Object:
from initial matrix -> target matrix
Input:
1. k the count of test caese
2. m n the count of rows and columns
3. the numbers of the inital matrix and the target matrix
Output
the least steps from initial matrix to target matrix, if it is not possible to transfer from initial to target, output -1.
sample intput
2
4 3
1 0 1
0 0 0
1 1 0
1 0 1
1 0 1
1 1 1
0 1 1
1 0 1
4 3
1 0 1
0 0 0
1 0 0
1 1 1
1 1 0
1 1 1
0 1 1
1 0 1
sample output
2
-1
I have coded one solution: mysolution.cc, which enumerate all posibilities and which is correct but it is too slow, could you provide a correct but fast solution.
Thanks.

The rows always stay in the same place, so if row r starts with k ones, it will always have either k ones or columns - k.
for each row, check if count_of_ones(initial,row) == count_of_ones(target,row), if yes, fine, else check if count_of_ones(initial,row) = columns - count_of_ones(target,row), if so, flip row, else output -1. As #maniek pointed out, it's not so easy when exactly half of the columns contain ones. Such rows would have to be treated in step 2 to try and form the required columns.
for each column, count the number of ones int the target and the working matrix (after flipping rows as appropriate). If the sequences of counts are not permutations of each other, output -1, otherwise try to find a permutation of columns that transforms working to target (any columns identical between working and target have to be kept fixed). If not possible, output -1, otherwise find minimum number of swaps necessary to achieve that permutation.

I will give you some thoughts. You compare row by row. If the i-th row of the first matrix has the same number of 1 as in the i-th row of the second matrix - then you don't inverse. If the i-th row of the first matrix has the same number of 1 as the 0 in the i-th row of the second matrix - then you must inverse. If neither of this is true, then there is no solution. This is all about inversing.
Now all columns are equal but in a different order(the second matrix has permuted columns from the first matrix). If the columns are not permutation of each other - return -1. This problem is equal to find the minimum number of swaps to convert a one permutation to other.

Related

Can we really avoid extra space when all the values are non-negative?

This question is a follow-up of another one I had asked quite a while ago:
We have been given an array of integers and another number k and we need to find the total number of continuous subarrays whose sum equals to k. For e.g., for the input: [1,1,1] and k=2, the expected output is 2.
In the accepted answer, #talex says:
PS: BTW if all values are non-negative there is better algorithm. it doesn't require extra memory.
While I didn't think much about it then, I am curious about it now. IMHO, we will require extra memory. In the event that all the input values are non-negative, our running (prefix) sum will go on increasing, and as such, sure, we don't need an unordered_map to store the frequency of a particular sum. But, we will still need extra memory (perhaps an unordered_set) to store the running (prefix) sums that we get along the way. This obviously contradicts what #talex said.
Could someone please confirm if we absolutely do need extra memory or if it could be avoided?
Thanks!
Let's start with a slightly simpler problem: all values are positive (no zeros). In this case the sub arrays can overlap, but they cannot contain one another.
I.e.: arr = 2 1 5 1 1 5 1 2, Sum = 8
2 1 5 1 1 5 1 2
|---|
|-----|
|-----|
|---|
But this situation can never occur:
* * * * * * *
|-------|
|---|
With this in mind there is algorithm that doesn't require extra space (well.. O(1) space) and has O(n) time complexity. The ideea is to have left and right indexes indicating the current sequence and the sum of the current sequence.
if the sum is k increment the counter, advance left and right
if the sum is less than k then advance right
else advance left
Now if there are zeros the intervals can contain one another, but only if the zeros are on the margins of the interval.
To adapt to non-negative numbers:
Do as above, except:
skip zeros when advancing left
if sum is k:
count consecutive zeros to the right of right, lets say zeroes_right_count
count consecutive zeros to the left of left. lets say zeroes_left_count
instead of incrementing the count as before, increase the counter by: (zeroes_left_count + 1) * (zeroes_right_count + 1)
Example:
... 7 0 0 5 1 2 0 0 0 9 ...
^ ^
left right
Here we have 2 zeroes to the left and 3 zeros to the right. This makes (2 + 1) * (3 + 1) = 12 sequences with sum 8 here:
5 1 2
5 1 2 0
5 1 2 0 0
5 1 2 0 0 0
0 5 1 2
0 5 1 2 0
0 5 1 2 0 0
0 5 1 2 0 0 0
0 0 5 1 2
0 0 5 1 2 0
0 0 5 1 2 0 0
0 0 5 1 2 0 0 0
I think this algorithm would work, using O(1) space.
We maintain two pointers to the beginning and end of the current subsequence, as well as the sum of the current subsequence. Initially, both pointers point to array[0], and the sum is obviously set to array[0].
Advance the end pointer (thus extending the subsequence to the right), and increase the sum by the value it points to, until that sum exceeds k. Then advance the start pointer (thus shrinking the subsequence from the left), and decrease the sum, until that sum gets below k. Keep doing this until the end pointer reaches the end of the array. Keep track of the number of times the sum was exactly k.

How to count the number of permutations?

We are given array-'a' and array-'b' consisting of positive integers.
How can I count all the permutation of array 'a' which are strictly lexicographically smaller than array-'b'?
Arrays can contain as many as 10^5 integers(positive)
Example:
1 2 3 is lexicographically smaller than 3 1 2
1 2 3 is lexicographically smaller than 1 4 5.
I would like the solution to be in C++.
Input : 3
1 2 3
2 1 3
Output : 2
Only permutations 1,2,3 and 1,3,2 are lexicographically smaller than 2 1 3
Let's just tackle the algorithm. Once you get that figured out, the implementation should be pretty straightforward. Does this look like it does what you're looking for?
Pseudo code:
function get_perms(a,b)
#count the number of digits in a that are <b[0]
count = sum(a<b[0])
Nperms = (len(a)-1)! #modify this formula as needed
N = count*Nperms
if sum(a==b[0]) > 0
remove 1 b[0] from a
# repeat the process with the substring assuming a[0]==b[0]
N += sum(a==b[0])*get_perms(a,b[1:end])
return N
main()
get_perms(a,b)
Edit: I did a little searching. I believe that this is what you are looking for.

Is there a way to insert row/column in matrix (Eigen C++)?

I am using the Eigen library in C++.
I need to insert a row and column to an existing matrix at specific index.
For example, say I need to insert a 0 row and 0 column at the 2nd index...
ORIGINAL MATRIX (A)
1 2 3
1 2 3
1 2 3
NEW MATRIX (B)
1 2 0 3
1 2 0 3
0 0 0 0
1 2 0 3
Thanks for the help in advance!
The new matrix B can be constructed from the original matrix A by using the block operations .topRows() and .bottomRows():
MatrixXd B = MatrixXd::Zero(4, 3);
B.topRows(2) = A.topRows(2);
B.bottomRows(1) = A.bottomRows(1);
This will insert a row of zeros between the second and third row. Analogous operations with .rightCols() and .leftCols() can be used to insert a column of zeros.

Intuition behind working with `k` to find the kth-symbol in the grammar

I took part in a coding contest wherein I encountered the following question:
On the first row, we write a 0. Now in every subsequent row, we look at the previous row and replace each occurrence of 0 with 01, and each occurrence of 1 with 10. Given row N and index K, return the K-th indexed symbol in row N. (The values of K are 1-indexed.)
While solving the question, I solved it like a level-order traversal of a tree, trying to form the new string at each level. Unfortunately, it timed-out. I then tried to think along the terms of caching the results, etc. with no luck.
One of the highly upvoted solutions is like this:
class Solution {
public:
int kthGrammar(int N, int K) {
if (N == 1) return 0;
if (K % 2 == 0) return (kthGrammar(N - 1, K / 2) == 0) ? 1 : 0;
else return (kthGrammar(N - 1, (K + 1) / 2) == 0) ? 0 : 1;
}
};
My question is simple - what is the intuition behind working with the value of K (especially, the parities of K)? (I hope to be able to identify such questions when I encounter them in future).
Thanks.
Look at the sequence recursively. In generating a new row, the first half is identical to the process you used to get the previous row, so that part of the expansion is already done. The second half is merely the same sequence inverted (0 for 1, 1 for 0). This is one classic way to generate a parity map: flip all the bits and append, representing adding a 1 to the start of each binary number. Thinking of expanding the sequence 0-3 to 0-7, we start with
00 => 0
01 => 1
10 => 1
11 => 0
We now replicate the 2-digit sequence twice: first with a leading 0, which preserves the original parity; second with a leading 1, which inverts the parity.
000 => 0
001 => 1
010 => 1
011 => 0
100 => 1
101 => 0
110 => 0
111 => 1
Is that an intuition that works for you?
Just for fun, as a different way to solve this, consider that the nth row (0-indexed) has 2^n elements in it, and a determination as to the value of the kth (0-indexed) element can be made soley according to the parity of how many bits are set in k.
The check for parity in the code you posted is just to make the division by two correct, there's no advanced math or mystery hiding here :) Since the pattern is akin to a tree, where the pattern size multiplies by two for each added row, correctly dividing points to the element's parent. The indexes in this question are said to be "1-indexed;" if the index is 2, dividing by two yields the parent index (1) in the row before; and if the index is 1, dividing (1+1) by two yields that same parent index. I'll leave it to the reader to generalize that to ks parity. After finding the parent, the code follows the rule stated in the question: if the parent is 0, the left-child must be 0 and right-child 1, and vice versa.
0
0 1
0 1 1 0
0 1 1 0 1 0 0 1
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0
a a b a b b a
0 01 0110 01101001 0110100110010110
a b b a b a a b
0110100110010110 1001011001101001

How to fill in a matrix recursively in c++?

So I have to fill in a square matrix recursively. For size N=5, it should be:
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
but my program shows:
1 1 1 1 1
1 2 2 2 1
1 2 3 3 1
1 2 2 2 1
1 1 1 1 1
void llenar5 (int** mat, int n, int f=0, int c=0,int k=2)
{
if (f<n)
{
if (c<n)
{
if (f==0 ||c==0||f==n-1||c==n-1)
{
*(*(mat+f)+c)=1;
llenar5(mat,n,f,c+1,k); //move to the right
}
else if (f==k-1 ||c==k-1||f==n-k||c==n-k)
{
*(*(mat+f)+c)=k;
llenar5(mat,n,f,c+1,k++);
}
}
llenar5(mat,n,f+1,c,k);
}
}
I am creating a matrix in dynamic memory, and I tried calling the function llenar5(mat,n,f+1,c+1,k+1) to jump a column and row while incrementing the values.
void llenar5 (int** mat, int n, int f=0, int c=0,int k=1)
{
if (f<n)
{
if (c<n)
{
if (f==k-1 ||c==k-1||f==n-k||c==n-k)
{
*(*(mat+f)+c)=k;
llenar5(mat,n,f,c+1,k+1);
}
llenar5(mat,n,f,c+1,k);
}
llenar5(mat,n,f+1,c,k);
}
}
I think it will help if you, temporarily, consider a matrix with 0-based numbers. For example, your initial matrix would look instead something like this:
0 0 0 0 0
0 1 1 1 0
0 1 2 1 0
0 1 1 1 0
0 0 0 0 0
If you inspect this matrix, you should quickly observe a fundamental property of this matrix. The value of each cell is the minimum distance from the cell to its closest horizontal or vertical edge.
So, for cell at coordinates (x,y), with the matrix of size w (width) and h (height), the value of each cell is:
min(x, y, (w-1-x), (h-1-y))
Where the min() function is a classical minimum function, that computes the minimum value of its arguments.
Then, it should be obvious that going from a 0-based matrix to a 1-based matrix you should simply add 1 to the result.
So, in conclusion your code should be trivially simple:
Loop over all the x and y coordinates.
Set the value of the corresponding cell based on the above formula.
Your code seems to be unnecessarily complicated. All that recursion is completely unneeded. This can be done using a single pass over their entire matrix, top to bottom, left to right. You don't need to know the values of adjacent cells, to compute the value in the next cell.