I need to do some task.
There are numbers give in two rows and they act like pairs of integers (a, b). I have to find the maximum 5 numbers of the a-row and then select the max of those 5 but this time from the b-row. Ex:
1 4
5 2
3 3
7 5
6 6
2 9
3 1
In this example, the pair i need is (6,6) because 6 (a) is in the top 5 of the a[i] numbers and 6 (b) is the maximum in the b section of those 5 pairs.
I was thinking of doing this with vectors and my own defined structures, also use some temp arrays but i don't know if that's the right thing to do maybe there is simpler way to do this.
Any ideas ?
EDIT: I also need the index number of the pair (in the case that is 5, it's the fifth pair i.e).
A priority queue holding pairs that does its order evaluations based on the first element of the pair would be appropriate. You could insert all the pairs and then extract the top 5. Then just iterate on that list of pairs looking for the max of the second element of each pair.
edit
I should say that it is a decent solution only if you can accept a runtime on the order of O(n * lg n)
Alternate approaches:
Push triples (first, second, index) into a vector and then std::partial_sort the first 5 items using a descending order functor on the first element. Then use std::max_element with a second functor to find the max of the second element, and grab its index. If I'm reading the complexity of partial_sort correctly this should run in linear time (O(n)) because we're always sorting a max of 5 elements rather than O(n*log n).
Similarly, have the vector only contain pairs and sort a second vector containing indexes into the first one.
Related
The problem is:
You have to sort an array in ascending order(permutation: numbers from 1 to N in a random order) using series of swaps. Every swap has a price and there are 5 types of prices. Write a program that sorts the given array for the smallest price.
There are two kinds of prices: priceByValue and priceByIndex. All of the prices of a kind are given in 2 two-dimensional arrays N*N. Example how to access prices:
You want to swap the 2nd and the 5th elements from the permutation with values of 4 and 7. The price for this swap will be priceByValue[4][7] + priceByIndex[2][5].
Indexes of all arrays are counted from 1 (, not from 0) in order to have access to all of the prices (the permutation elements’ values start from 1): priceByIndex[2][5] would actually be priceByIndex[1][4] in code. Moreover, the order of the indexes by which you access prices from the two-dimensional arrays doesn’t matter: priceByIndex[i][j] = priceByIndex[j][i] and priceByIndex[i][i] is always equal to 0. (priceByValue is the same)
Types of prices:
Price[i][j] = 0;
Price[i][j] = random number between 1 and 4*N;
Price[i][j] = |i-j|*6;
Price[i][j] = sqrt(|i-j|) *sqrt(N)*15/4;
Price[i][j] = max(i,j)*3;
When you access prices by index i and j are the indexes of the elements you want to swap from the original array; when you access prices by value i and j are the values of the elements you want to swap from the original array. (And they are always counted from 1)
Things given:
N - an integer from 1 to 400, Mixed array, Type of priceByIndex, priceByIndex matrix, Type of priceByValue, priceByValue matrix. (all elements of a matrix are from the given type)
Things that should 'appear on the screen': number of swaps, all swaps (only by index - 2 5 means that you have swapped 2nd and 3rd elements) and the price.
As I am still learning C++, I was wondering what is the most effective way to sort the array in order to try to find the sort with the smallest cost.
There might be a way how to access series of swaps that result a sorted array and see which one is with the smallest price and I need to sort the array by swapping the elements which are close by both value and index, but I don’t know how to do this. I would be very grateful if someone can give me a solution how to find the cheapest sort in code. Thank you in advance!
More: this problem might have no solution, I am just trying to get a result close to the ideal.
Dynamic Programming!
Think of the problem as a graph. Each of the N-factorial permutations represents a graph vertex, and the allowed swaps are just arcs between vertices. The price-tag of a swap is just the weight on the arc.
When you look at the problem this way, it can be easily solved with Dijkstra's algortihm for finding the lowest cost path through a graph from one vertex to another.
This is also called Single Pair Shortest Path
you can use an algorithm for sorting an array in lexicographical order and modify it so that it fits your needs ( you did not mention the sorting criteria like the desired result i.e. least value first, ... ) there are multiple algorithms available for this, i.e. quick sort,...
a code example is in https://www.geeksforgeeks.org/lexicographic-permutations-of-string/
for example if
a[3]={1,2,3}
1,2,3,1+2,2+3,1+2+3
so my program should print
1
2
3
3
5
8
I know there exits a formula for calculating the total sum.
But what i want is efficient method to calculate individual sums.
A seg tree advisable?
Assuming that by subarray you mean what some authors conventionally call subarray being a contiguous slice of an array, you are looking for Kadane's algorithm.
It works by incrementally finding the biggest subarray. At any given point of the search, the maximum subarray on that index is either the empty array (sum == zero) or consists of one more element than the maximum subarray that ended at the previous position. You keep track of what is the best you've ever found so you can compare subarrays with the best so far and return the actual best solution.
It may also be extended to multiple dimensions.
Recently, when I need to iterate through a std::map I usually build a std::vector from the map, since the complexity to access an element is (log N) (indeed, only when I need to access elements by a custom key).
So, I end up maintaining a std::vector just for iterating all my elements, (since its complexity is constant O(1)) and a std::map for specific retrieving (since its complexity is O(log n) when iterating).
Is this a correct way to do it, or should I just go with the std::map and forget about the std::vector (you know, for this specific case).
Thank you.
You should forget about the vector unless profiling tells you you need it. Iterating in a map is NOT O(log2N) per iterator increment... it only needs to find the next element by traversing the minimum path from the current element in the balanced binary tree... that's often only following a link or two, though the worst-case step of moving from the last left-side node to the first right-side node requires 2*(log2(N)-1) movements if it just uses a generic approach.
To visualise this, consider nodes in the map below - they're always in sorted order, and here I'm assuming the data elements happen to be incrementing integers as we can then easily refer to the nodes using their values:
8
/ \
4 12
/ \ / \
2 6 10 14
/ \ / \ / \ / \
1 3 5 7 9 11 13 15
As you traverse, your iterator may have to start at the root "8" and traverse the left hand branches to "1", but then it moves up a single link to 2, then down a single link to "3", before having to pop up a couple links to "4" and down a couple to "5". Clearly - most of the time it's just following 1 or 2 links, with longer paths increasingly rare: if we list it all out:
6 links: once/x1: 7-6-4-8-12-19-9
3 links: 8-1
2 links: x4: 3-2-4, 4-6-5, 11-10-12, 12-14-13
1 link: x8: 1-2, 2-3, 5-6, 6-7, 9-10, 10-11, 13-14, 14-15
Total is 8*1 + 2*4 + 3*1 + 6*1 = 25... 25 links traversed to iterate 15 elements.
That sequence can be generalised for arbitrary N as: N/2 + 4N/8 + 6N/16 + 10N/32 + 12N/128 + 14N/256... 2iN/2i+1.... if we simplify the fractions and divide by N we get a series:
1/2, 1/2, 3/8, 1/4, 5/32, 3/32, 7/128, ...
There are lots of proofs here that it converses to 2N, i.e. the average number of links per increment of the iterator converges to 2 with large N, and as 2 is a constant factor we can still say incrementing the iterator is O(1).
I'm studying Binary trees! and i have a problem in this Homework.
I have to use binary trees to solve this problem
here is the problem :
You are given a list of integers. You then need to answer a number of questions of the form: "What is the maximum value of the elements of the list content between the A index and the index B?".
example :
INPUT :
10
2 4 3 5 7 19 3 8 6 7
4
1 5
3 6
8 10
3 9
OUTPUT:
7
19
8
19
TIME LIMITS AND MEMORY (Language: C + +)
Time: 0.5s on a 1GHz machine.
Memory: 16000 KB
CONSTRAINTS
1 <= N <= 100000, where N is the number of elements in the list.
1 <= A, B <= N, where A, B are the limits of a range.
1 <= I <= 10 000, where I is the number of intervals.
Please do not give me the solution just a hint !
Thanks so much !
As already discussed in the comments, to make things simple, you can add entries to the array to make its size a power of two, so the binary tree has the same depth for all leaves. It doesn't really matter what elements you add to this list, as you won't use these computed values in the actual algorithm.
In the binary tree, you have to compute the maxima in a bottom-up manner. These values then tell you the maximum of the whole range these nodes are representing; this is the major idea of the tree.
What remains is splitting a query into such tree nodes, so they represent the original interval using less nodes than the size of the interval. Figure out "the pattern" of the intervals the tree nodes represent. Then figure out a way to split the input interval into as few nodes as possible. Maybe start with the trivial solution: just split the input in leave nodes, i.e. single elements. Then figure out how you can "combine" multiple elements from the interval using inner nodes from the tree. Find an algorithm doing this for you by not using the tree (since this would require a linear time in the number of elements, but the whole idea of the tree is to make it logarithmic).
Write some code which works with an interval of size 0. It will be very simple.
Then write some for a interval of size 1. It will still be simple.
Then write some for an interval of size 2. It may need a comparison. It will still be simple.
Then write some for an interval of size 3. It may involve a choice of which interval of size 2 to compare. This isn't too hard.
Once you've done this, it should be easy to make it work with any interval size.
An array would be the best data structure for this problem.
But given you need to use a binary tree, I would store (index, value) in the binary
tree and key on index.
I am keeping the nonzeros of a sparse matrix representation in some triplets, known in the numerical community as Compressed Sparse Row storage, entries are stored row-wise, for instance a 4x4 matrix is represented as
r:0 0 1 1 2 2 3 3 3
c:0 3 2 3 2 3 1 2 3
v:1 5 2 2 4 1 5 4 5
so 'r' gives row indices, 'c' gives column indices and 'v' are the values associated to the 2 indices above that value.
I would like to delete some rows and columns from my matrix representation, say rows and cols: 1 and 3. So I should remove 1s and 3s from the 'r' and 'c' arrays. I am also trying to learn more about the performance of the stl containers and read a bit more. As first try, created a multimap and delete the items by looping over them with the find method of multimap. This removes the found keys however might leave some of the searched values in the 'c' array then I swapped the key,value pairs and do the same operation for this second map, however this did not seem to be a very good solution to me, it seems to be pretty fast(on a problem with 50000 entries), though. So the question is what would be the most efficient way to do this with standard containers?
You could use a map (between a pair of rows and columns) and the value, something like map<pair<int,int>, int>
If you then want to delete a row, you iterate over the elements and erase those with the to-be deleted row. The same can be done for columns.
How are you accessing the matrix? Do you look up particular rows/columns and do things with them that way, or do you use the whole matrix at a time for operations like matrix-vector multiplications or factorization routines? If you're not normally indexing by row/column, then it may be more efficient to store your data in std::vector containers.
Your deletion operation is then a matter of iterating straight through the container, sliding down subsequent elements in place of the entries you wish to delete. Obviously, there are tradeoffs involved here. Your map/multimap approach will take something like O(k log n) time to delete k entries, but whole-matrix operations in that representation will be very inefficient (though hopefully still O(n) and not O(n log n)).
Using the array representation, deleting a single row or column would take O(n) time, but you could delete an arbitrary number of rows or columns in the same single pass, by keeping their indices in a pair of hash tables or splay trees and doing a lookup for each entry. After the deletion scan, you could either resize the vectors down to the number of elements you have left, which saves memory but might entail a copy, or just keep an explicit count of how many entries are valid, trading dead memory for saving time.