graphs divisibility - c++

Given a simple undirected graph containing N vertices numbered 1 to N, each vertex containing a digit from {1,2,..7}. Starting at the vertex 1 with an empty string S, we travel through some vertices (with no limitations) to the vertex N. For every vertex on the way, we add the respective digit to the right of the string S. At last we get S as a decimal integer. You are requested to find such a way satisfying S is divisible by all of its digits, and the sum of digits of S must be as small as possible.
Input
There are several test cases (fifteen at most), each formed as follows:
The first line contains a positive integer N (N ≤ 100).
The second line contains N digits (separated by spaces), the i-th digit is the value of the i-th vertex.
N last lines, each contains N values of {0, 1} (separated by spaces), the j-th value of the i-th line is equal to 1 if there is an edge connecting two vertices (i, j), otherwise 0.
The input is ended with N = 0.
Output
For each test case, output on a line the minimum sum of digits found, or -1 if there's no solution.
example
Input:
4
1 2 1 4
0 1 1 1
1 0 0 1
1 0 0 1
1 1 1 0
Output:
7
please guide me
there can be self loops and cycles such that node 1 and node N can be visted any number of times

If given graph is transformed to some other graph, where cycles are not allowed, this problem can be solved with Dijkstra's algorithm.
To do this, let's start with string divisibility by 7. Look at this sequence: 1, 10, 100, ... (mod 7). Since 7 is a prime number, 107-1 = 1 (mod 7) because of Fermat's little theorem. Which means 1, 10, 100, ... (mod 7) sequence is periodic and period is 6. This will be used to transform the graph and also this allows to recursively compute Sn (mod 7) using Sn-1 (mod 7): Sn = Sn-1 + 10n%6 * n_th_digit (mod 7).
It's necessary to start shortest path search from node N because this path may be ended at one of the several nodes of the transformed graph. Also this allows to determine quickly (using first 2 nodes of the path), if it is allowed to visit node "5", node"4", and other "even" nodes.
Algorithm's open set (the priority queue) should contain the priority itself (sum of digits) as long as 3 additional bits and 3 remainders: is "4" allowed, is "3" visited, is "7" visited, S % 3, S % 7, and S.length % 6.
Graph should be transformed as follows. Each vertex is expanded to 3 vertexes, one is allowed only for S%3==0, others - for S%3==1 and S%3==2. Then each vertex is expanded to 7 (for S%7), and then each vertex is expanded to 6 (for S.length % 6). It is possible to fit all these expansions to the original graph: just add a 3D array (size 3*7*6) of back-pointers to each node. While searching for the shortest path, the non-empty back-pointers determine algorithm's closed set (they disallow cycles). When shortest path is found, back-pointers allow to reconstruct the sequence of nodes in this path. And the moment when shortest path is found is determined by visiting node 1 with (node_3_not_visited || S%3==0) && (node_7_not_visited || S%7==0).

First mathematically find the LCM of the numbers given in the set.
lemme paraphrase the scenario .... given a set of numbers... find the LCM then traverse the vetices in such a way that the their path makes the number .Since its LCM it is number whose sum is mininum
For set {0,1,2,3,4} LCM is 12 so travers from 1 to 2
for set {0,1,2,3,4,5,6,7} LCM is 420..(I think i am right)

Use the A* search algorithm, where the "cost" is the sum of the digits, and divisibility determines which edges you can traverse.

Related

Finding the permutation that satisfy given condition

I want to find out the number of all permutation of nnumber.Number will be from 1 to n.The given condition is that each ithposition can have number up to Si,where Si is given for each position of number.
1<=n<=10^6
1<=si<=n
For example:
n=5
then its all five element will be
1,2,3,4,5
and given Si for each position is as:
2,3,4,5,5
It shows that at:
1st position can have 1 to 2that is 1,2 but can not be number among 3 to 5.
Similarly,
At 2nd position can have number 1 to 3 only.
At 3rd position can have number 1 to 4 only.
At 4th position can have number 1 to 5 only.
At 5th position can have number 1 to 5 only.
Some of its permutation are:
1,2,3,4,5
2,3,1,4,5
2,3,4,1,5 etc.
But these can not be:
3,1,4,2,5 As 3 is present at 1st position.
1,2,5,3,4 As 5 is present at 3rd position.
I am not getting any idea to count all possible number of permutations with given condition.
Okay, if we have a guarantee that numbers si are given in not descending order then looks like it is possible to calculate the number of permutations in O(n).
The idea of straightforward algorithm is as follows:
At step i multiply the result by current value of si[i];
We chose some number for position i. As long as we need permutation, that number cannot be repeated, so decrement all the rest si[k] where k from i+1 to the end (e.g. n) by 1;
Increase i by 1, go back to (1).
To illustrate on example for si: 2 3 3 4:
result = 1;
current si is "2 3 3 4", result *= si[0] (= 1*2 == 2), decrease 3, 3 and 4 by 1;
current si is "..2 2 3", result *= si[1] (= 2*2 == 4), decrease last 2 and 3 by 1;
current si is "....1 2", result *= si[2] (= 4*1 == 4), decrease last number by 1;
current si is "..... 1", result *= si[3] (= 4*1 == 4), done.
Hovewer this straightforward approach would require O(n^2) due to decreasing steps. To optimize it we can easily observe that at the moment of result *= si[i] our si[i] was already decreased exactly i times (assuming we start from 0 of course).
Thus O(n) way:
unsigned int result = 1;
for (unsigned int i = 0; i < n; ++i)
{
result *= (si[i] - i);
}
for each si count the number of element in your array such that a[i] <= si using binary search, and store the value to an array count[i], now the answer is the product of all count[i], however we have decrease the number of redundancy from the answer ( as same number could be count twice ), for that you can sort si and check how many number is <= s[i], then decrease that number from each count,the complexity is O(nlog(n)), hope at least I give you an idea.
To complete Yuriy Ivaskevych answer, if you don't know if the sis are in increasing order, you can sort the sis and it will also works.
And the result will be null or negative if the permutations are impossible (ex: 1 1 1 1 1)
You can try backtracking, it's a little hardcore approach but will work.
try:
http://www.thegeekstuff.com/2014/12/backtracking-example/
or google backtracking tutorial C++

Finding numbers with given GCD values

I was looking over the Eucledian algorithm for finding GCD of numbers. Now, it can be used to find GCD of two given numbers. However, if I am given GCD of a single number with multiple other numbers, for example, GCD of the first number with 3 other numbers (including itself), that is,
Given is: GCD of a with a, GCD of a with b, GCD of a with c, GCD of a with d.
and same goes for the other numbers, i.e. GCD of b with a, b with b, .....
Then, how can I find the individual numbers? I know that GCD(a,a) = a itself but the problem here is, that the individual GCD given are in a random order, and therefore, I don't know which input number is the GCD of which two numbers. In that case, how do I find the individual numbers?
Here is my GCD code:
int gcd(int a,int b)
{
if(b==0)
{
return a;
}
return gcd(b,a%b);
}
Example: Let's say the input given is,
3 1 3 1 4 2 2 3 6
3 //(total numbers we have to find in original array)
Then output should be, 3 4 6. Because if you calculate GCD pairwise (total 9 pairs and hence 9 numbers as input) of each of these numbers, then we get the output as above.
Explanation: 3 -> GCD of (3,3)
1 -> GCD of (3,4)
3 -> GCD of (3,6)
1 -> GCD of (4,3)
4 -> GCD of (4,4)
2 -> GCD of (4,6)
6 -> GCD of (6,6)
3 -> GCD of (6,3)
2 -> GCD of (6,4)
Therefore, I have to find the numbers whose GCD is given as input. Hence, (3,4,6) are those numbers.
I think you can do this by the following process:
Find and remove largest number, this is one of the original numbers
Compute the gcd of the number just found in step 1, with all numbers previously found in step 1.
Remove each of these computed gcds from the input array of gcds (Strictly speaking remove 2 copies of each gcd)
Repeat until all numbers are found
The point is that this only goes wrong if the largest number x found in step 1 is not one of the original numbers. However, this can only happen if x is a gcd of two other numbers. These other numbers must be at least as large as x, but all such gcds have been removed in step 3. Therefore x is always one of the original numbers.
If the second line of the input is 1, then the first line of the input will have only one number, and due to your observation that gcd(a, a) = a, the value of a will be whatever value is on the first line of input.
If the value on the second line of input is greater than 1, then the problem can be reduced using the following observation. Given positive integers a and b, we know that gcd(a, b) <= a = gcd(a, a) and gcd(a, b) <= b = gcd(b, b) will always hold. Therefore, we can conclude that the largest two numbers on the first line of input must both be part of the basic set of numbers. The largest two numbers may be equal, but in your example, they are 4 and 6, and they are not equal.
If there are more than two numbers to find, let's call the largest two a and b. Since we now know the value of a and b, we can compute gcd(a, b) and remove two occurrences of that value from consideration as one of the input numbers. We remove two occurrences because gcd(a, b) = gcd(b, a) are both in the list of input numbers. Then using similar logic, we conclude that the largest number remaining after a, b, gcd(a, b), and gcd(b, a) are removed must be one of the input numbers.
Wash, rinse, repeat.
This is actually pretty easy:
count how many times each distinct number appears in the array
if that count is odd, then that is one of the numbers in your set
if that count is even, that is not one of the numbers in your set.
done.
This works because when x != y, gcd(x,y) = gcd(y,x) and that number will be in the array twice. Only values that come from gcd(x,x) will be in the array once, leading to an odd number of that specific value.
As we see here, that for each number with other number a GCD is calculated and added to the existing list, like this in the end we would be having n*n total numberer for original n numbers. So the same approach can be reverse used to find original numbers
Sort the list in descending order.
Collect top n^(0.5) numbers, that would be our answer.
For your example
3 1 3 1 4 2 2 3 6
Sorted = 6 4 3 3 3 2 2 1 1
value of n = 9
value of n^(0.5) = 3
choose top 3 numbers 6,4 and 3. Thats our answer

How to find the largest sum with the smallest possible path in a tetrahedron of integers?

First here is the question,
Say that an integer can be represented as a perfect sphere, in which the value of the sphere is equal to the integer it contains. The spheres are organized into a tetrahedral pyramid in which N = the length of the side, N being between 1 and 15. Pick (a possibly empty) subset of sphere's such that their sum of values is maximized. Note that the sphere can hold a negative value so it is not necessarily desirable to pick up every sphere. We do not want to disorganize the pyramid so we cannot take any one sphere without first taking the ones above it.
Input Format:
Line 1: integer N
Line 2: N(N+1)/2+1
Output Format:
Line 1: One integer, the maximum sum of values achievable
Sample Input:
3
5
-2 -7
-3
1 0 8
0 3
2
Sample Output:
8
Here is a sample solution given to my understanding so far:
The best solution is shown as bold in the diagram bellow. It is not smart to take 1 because that would require taking -2, decreasing the total. There for 8, 3, and 2 should be taken because they outweigh -3 and -7.
My question is,
How do I store the input so that I can retain the proper order? Or do i even need to? I am trying to use a queue but my program gets very lengthly because I have to find the sum for each possible path and then compare each sum to find the max. I am also having a lot of difficulty breaking the data up into the right pattern so I don't recount a number or take one out of sequence. Is there a more efficient way to do this? Can Dijkstra's algorithm be of any use in this case? If so, then how? Any help is greatly appreciated!!
I would use a 3-dimensional array. To use your example:
A[0][0][0] = 5
A[1][0][0] = -2
A[1][1][0] = -3
A[1][0][1] = -7
A[2][0][0] = 1
A[2][1][0] = 0
A[2][2][0] = 2
A[2][0][0] = 0
A[2][1][0] = 3
A[2][0][0] = 8
The "above" relationship is simply a matter of index arithmetic: [ia, ja, ka] is above [ia+1, ja, ka], [ia+1, ja+1, ka] and [ia+1, ja, ka+1].

Count the number of paths in DAG with length K

I have a DAG with 2^N nodes, with values from 0 to 2^N-1. There is edge from x to y if x < y and x (xor) y = 2^p, x and y being the node values and p a non-negative integer.
Since N can be as large as 100000, generating the graph and than proceeding with the counting would take much computational time. Is there any way to count the paths with certain length K (K being the number of edges between two nodes), differently stated, is there an equation of some sort for this kind of counting?
Thanks in advance
Michael's got some good insights, but I'm not sure I follow his entire argument. Here's my solution.
Let's say N=4, K=2. So the nodes range from 0 (00002) to 15 (11112).
Now let's consider node 2 (00102). There's an edge from 2 to 3 (00112) because 2 < 3 and xor(2,3) = 1 = 20. There's also an edge from 2 to 6 because 2 < 6 and xor(2,6) = 4 = 22. And there's an edge from 2 to 10 because 2 < 10 and xor(2,10) = 8 = 23.
To generalize: for any x, consider all of the 0 bits in x. By flipping any of the 0 bits to 1, you get a number y that's larger than x and differs from x by one bit. So there's an edge from x to that y.
The number of 1 bits in x is typically called the population count of x. I'll use pop(x) to mean the population count of x.
We're dealing with N-bit numbers (when we include leading zeroes), so the number of 0 bits in x is N - pop(x).
Let's use the term “j-path” to mean a path of length j. We want to count the number of K-paths.
Every node x has N - pop(x) outgoing edges. Each of these edges is a 1-path.
Let's consider node 5 (01012). Node 5 has an edge to 7 (01112), and node 7 has an edge to 15 (11112). Node 5 also has an edge to 13 (11012), and node 13 has an edge to 15 (11112). So there are two 2-paths out of node 5: 5-7-15 and 5-13-15.
Next let's look at node 2 (00102) again. Node 2 has an edge to 3 (00112), which has edges to 7 (01112) and 11 (10112). Node 2 also has an edge to node 6 (01102), which has edges to 7 (01112) and 14 (11102). Finally, node 2 has an edge to node 10 (10102), which has edges to 11 (10112) and 14 (11102). In all, there are six 2-paths out of node 2: 2-3-7, 2-3-11, 2-6-7, 2-6-14, 2-10-11, and 2-10-14.
The pattern is that, for any node x with z bits set to zero, where z ≥ K, there are some K-paths out of x. To find a K-path out of x, you pick any K of the zero bits. Flipping those bits to 1, one by one, gives you the path. You can flip the bits in any order you want; each order gives a different path.
When you want to pick k items, in a specific order, from a set of n items, that's called an ordered sample without replacement, and there are n! / (n-k)! ways to do it. This is often written nPk, but it's easier to type P(n,k) here.
So, the nodes that have exactly 2 zero bits have P(2,2) = 2! / (2-2)! = 2 2-paths out of them. (Note that 0! = 1.) The nodes that have exactly 3 zero bits have P(3,2) = 3! / 1! = 6 2-paths out of them. The node that has exactly 4 zero bits has P(4,2)= 4! / 2! = 12 2-paths out of it. (Since I'm using N=4 for the example, there is only one node with exactly 4 zero bits, which is node 0.)
But then we need to know, how many nodes have exactly 2 zero bits? Well, when there are n items to choose from, and we want to choose k of them, and we don't care about the order of the chosen items, that's called an unordered sample without replacement, and there are n! / (k! (n-k)!) ways to do it. This is called “n choose k”, and it's usually written in a way that I can't reproduce on stack overflow, so I'll write it as C(n,k).
For our example with N=4, there are C(4,2) = 6 nodes with exactly 2 bits set to zero. These nodes are 3 (00112), 5 (01012), 6 (01102), 9 (10012), 10 (10102), and 12 (11002). Each of these nodes has P(2,2) 2-paths out of it, so that means there are C(4,2) * P(2,2) = 6 * 2 = 12 2-paths out of nodes with exactly two 0 bits.
Then there are C(4,3) = 4 nodes with exactly 3 bits set to zero. These nodes are 1 (00012), 2 (00102), 4 (01002), and 8 (10002). Each of these nodes has P(3,2) 2-paths out of it, so there are C(4,3) * P(3,2) = 4 * 6 = 24 2-paths out of nodes with exactly three 0 bits.
Finally, there is C(4,4) = 1 node with exactly 4 bits set to zero. This node has P(4,2) = 12 2-paths out of it.
So the total number of 2-paths when N=4 is C(4,2)*P(2,2) + C(4,3)*P(3,2) + C(4,4)*P(4,2) = 12 + 24 + 12 = 48.
For general N and K (where K ≤ N), the number of K-paths is the sum of C(N,z) * P(z,K) for K ≤ z ≤ N.
I can type that into Wolfram Alpha (or Mathematica) like this:
Sum[n!/(z! (n - z)!) z!/(z - k)!, {z, k, n}]
And it simplifies it to this:
2^(n-k) n! / (n-k)!
The stated problem seems to be equivalent to this one:
Consider the set of all possible binary strings of length N. Consider operation Fi that flips i-th bit from 0 to 1. For strings x & y denote |x| the number of set bits, x
It's easy to see that one can obtain y from x by a series of exactly K operations Fi if and only if (x,y) is K-admissible. Moreover, if we fix x and sum up over all y such that (x,y) is K-admissible we get (N-|x|)!
Finally, we need to sum up over all x with |x|<=(N-K). For a given choice of |x| we have N!/(N-|x|)!|x|! possible choices of x. Combine with the above and you get that for the given |x| there are N!/|x|! possible paths.
Denote |x|=M, with M from 0 to N-K, and your answer is the sum over all M of N!/M!

Similar to subset sum [duplicate]

This problem was asked to me in Amazon interview -
Given a array of positive integers, you have to find the smallest positive integer that can not be formed from the sum of numbers from array.
Example:
Array:[4 13 2 3 1]
result= 11 { Since 11 was smallest positive number which can not be formed from the given array elements }
What i did was :
sorted the array
calculated the prefix sum
Treverse the sum array and check if next element is less than 1
greater than sum i.e. A[j]<=(sum+1). If not so then answer would
be sum+1
But this was nlog(n) solution.
Interviewer was not satisfied with this and asked a solution in less than O(n log n) time.
There's a beautiful algorithm for solving this problem in time O(n + Sort), where Sort is the amount of time required to sort the input array.
The idea behind the algorithm is to sort the array and then ask the following question: what is the smallest positive integer you cannot make using the first k elements of the array? You then scan forward through the array from left to right, updating your answer to this question, until you find the smallest number you can't make.
Here's how it works. Initially, the smallest number you can't make is 1. Then, going from left to right, do the following:
If the current number is bigger than the smallest number you can't make so far, then you know the smallest number you can't make - it's the one you've got recorded, and you're done.
Otherwise, the current number is less than or equal to the smallest number you can't make. The claim is that you can indeed make this number. Right now, you know the smallest number you can't make with the first k elements of the array (call it candidate) and are now looking at value A[k]. The number candidate - A[k] therefore must be some number that you can indeed make with the first k elements of the array, since otherwise candidate - A[k] would be a smaller number than the smallest number you allegedly can't make with the first k numbers in the array. Moreover, you can make any number in the range candidate to candidate + A[k], inclusive, because you can start with any number in the range from 1 to A[k], inclusive, and then add candidate - 1 to it. Therefore, set candidate to candidate + A[k] and increment k.
In pseudocode:
Sort(A)
candidate = 1
for i from 1 to length(A):
if A[i] > candidate: return candidate
else: candidate = candidate + A[i]
return candidate
Here's a test run on [4, 13, 2, 1, 3]. Sort the array to get [1, 2, 3, 4, 13]. Then, set candidate to 1. We then do the following:
A[1] = 1, candidate = 1:
A[1] ≤ candidate, so set candidate = candidate + A[1] = 2
A[2] = 2, candidate = 2:
A[2] ≤ candidate, so set candidate = candidate + A[2] = 4
A[3] = 3, candidate = 4:
A[3] ≤ candidate, so set candidate = candidate + A[3] = 7
A[4] = 4, candidate = 7:
A[4] ≤ candidate, so set candidate = candidate + A[4] = 11
A[5] = 13, candidate = 11:
A[5] > candidate, so return candidate (11).
So the answer is 11.
The runtime here is O(n + Sort) because outside of sorting, the runtime is O(n). You can clearly sort in O(n log n) time using heapsort, and if you know some upper bound on the numbers you can sort in time O(n log U) (where U is the maximum possible number) by using radix sort. If U is a fixed constant, (say, 109), then radix sort runs in time O(n) and this entire algorithm then runs in time O(n) as well.
Hope this helps!
Use bitvectors to accomplish this in linear time.
Start with an empty bitvector b. Then for each element k in your array, do this:
b = b | b << k | 2^(k-1)
To be clear, the i'th element is set to 1 to represent the number i, and | k is setting the k-th element to 1.
After you finish processing the array, the index of the first zero in b is your answer (counting from the right, starting at 1).
b=0
process 4: b = b | b<<4 | 1000 = 1000
process 13: b = b | b<<13 | 1000000000000 = 10001000000001000
process 2: b = b | b<<2 | 10 = 1010101000000101010
process 3: b = b | b<<3 | 100 = 1011111101000101111110
process 1: b = b | b<<1 | 1 = 11111111111001111111111
First zero: position 11.
Consider all integers in interval [2i .. 2i+1 - 1]. And suppose all integers below 2i can be formed from sum of numbers from given array. Also suppose that we already know C, which is sum of all numbers below 2i. If C >= 2i+1 - 1, every number in this interval may be represented as sum of given numbers. Otherwise we could check if interval [2i .. C + 1] contains any number from given array. And if there is no such number, C + 1 is what we searched for.
Here is a sketch of an algorithm:
For each input number, determine to which interval it belongs, and update corresponding sum: S[int_log(x)] += x.
Compute prefix sum for array S: foreach i: C[i] = C[i-1] + S[i].
Filter array C to keep only entries with values lower than next power of 2.
Scan input array once more and notice which of the intervals [2i .. C + 1] contain at least one input number: i = int_log(x) - 1; B[i] |= (x <= C[i] + 1).
Find first interval that is not filtered out on step #3 and corresponding element of B[] not set on step #4.
If it is not obvious why we can apply step 3, here is the proof. Choose any number between 2i and C, then sequentially subtract from it all the numbers below 2i in decreasing order. Eventually we get either some number less than the last subtracted number or zero. If the result is zero, just add together all the subtracted numbers and we have the representation of chosen number. If the result is non-zero and less than the last subtracted number, this result is also less than 2i, so it is "representable" and none of the subtracted numbers are used for its representation. When we add these subtracted numbers back, we have the representation of chosen number. This also suggests that instead of filtering intervals one by one we could skip several intervals at once by jumping directly to int_log of C.
Time complexity is determined by function int_log(), which is integer logarithm or index of the highest set bit in the number. If our instruction set contains integer logarithm or any its equivalent (count leading zeros, or tricks with floating point numbers), then complexity is O(n). Otherwise we could use some bit hacking to implement int_log() in O(log log U) and obtain O(n * log log U) time complexity. (Here U is largest number in the array).
If step 1 (in addition to updating the sum) will also update minimum value in given range, step 4 is not needed anymore. We could just compare C[i] to Min[i+1]. This means we need only single pass over input array. Or we could apply this algorithm not to array but to a stream of numbers.
Several examples:
Input: [ 4 13 2 3 1] [ 1 2 3 9] [ 1 1 2 9]
int_log: 2 3 1 1 0 0 1 1 3 0 0 1 3
int_log: 0 1 2 3 0 1 2 3 0 1 2 3
S: 1 5 4 13 1 5 0 9 2 2 0 9
C: 1 6 10 23 1 6 6 15 2 4 4 13
filtered(C): n n n n n n n n n n n n
number in
[2^i..C+1]: 2 4 - 2 - - 2 - -
C+1: 11 7 5
For multi-precision input numbers this approach needs O(n * log M) time and O(log M) space. Where M is largest number in the array. The same time is needed just to read all the numbers (and in the worst case we need every bit of them).
Still this result may be improved to O(n * log R) where R is the value found by this algorithm (actually, the output-sensitive variant of it). The only modification needed for this optimization is instead of processing whole numbers at once, process them digit-by-digit: first pass processes the low order bits of each number (like bits 0..63), second pass - next bits (like 64..127), etc. We could ignore all higher-order bits after result is found. Also this decreases space requirements to O(K) numbers, where K is number of bits in machine word.
If you sort the array, it will work for you. Counting sort could've done it in O(n), but if you think in a practically large scenario, range can be pretty high.
Quicksort O(n*logn) will do the work for you:
def smallestPositiveInteger(self, array):
candidate = 1
n = len(array)
array = sorted(array)
for i in range(0, n):
if array[i] <= candidate:
candidate += array[i]
else:
break
return candidate