I have a list. I need to divide it into 4 groups, and the sum of each group is relatively average. The list can be sorted or not.
Give an example: list(1,1,4,2,2,3,5,6) -> Divide into (1,1,4), (2,2,3), (5), (6).
Thanks in advance here, I know this requires some algorithmic ability.
You have three things to play with here.
a set of numbers, no of segments and the average of each segment.
If two of these are set, the third is automatically set.
In your case, your set of numbers is pre-defined and the no of segments is predefined - hence the average is also pre-defined.
You need to find this average and then run through the numbers. If the segments are required to be contiguous as in your example, this is the only way to do this.
If the elements in the segment can be non contiguous, then there are a lot more possibilities and your chances of getting to an even distribution is also better. You can keep a track of the four segments and add to whatever segment seems to be furthest away from it's target average. This is a greedy way to do this.
Keep in mind that your array could be horribly skewed.
Say the average is 6 and your array looks like
{ 24 , 0 , 0 , 0 , 0 ,0 , 0 , 0}
The ONLY distribution possible here would be
{24} ,{ 0 } , {0 , 0 ,0 },{0 , 0 ,0 }
Perhaps find the average of each group like so: (1+1+4+2+2+3+5+6)/4=6 and keep track of the total sum of each group. If it is in a certain [allowable] range, say 1 or 2, then proceed to the next list.
Related
What is the logical way to approach this problem ?
I found the solution here : solution which looks simple to code but I am having some difficulty understanding it logically.
From the same blog I am not able to understand this line,
So the number that ends with 1 is equal to DP[n-1].
Is there an easier way in which this solution can be explained?
Assume you are going to express 10 as the sum of 1 and 3.Then you can express 10 as 9+1 or 7+3. Then number of different ways that 10 can be expressed is equal to sum of number of different ways that 9 and 7 can be expressed.
i.edp[10]=dp[9]+dp[7]
Just you need to think recursively. Suppose R(n) shows the number of ways to write n as the sum of 1 and 3s. The last number could be 1 or 3. If the last number is 1, we should count R(n-1), and if the last number is 3 we should count R(n-3). We know that the solution of these approach has not any overlap. Because the end number of each o them is different (one of them is 1 and the other one is 3).
Therfore, R(n) = R(n-1) + R(n-3).
In addition, to compute R(n), we need three initial values. R(1) = 1, R(2) = 1, and R(3) = 2.
I was solving a problem which states following:
There are n buckets in a row. A gardener waters the buckets. Each day he waters the buckets between positions i and j (inclusive). He does this for t days for different i and j.
Output the volume of the waters in the buckets assuming initially zero volume and each watering increases the volume by 1.
Input: first line contains t and n seperated by spaces.
The next t lines contain i and j seperated by spaces.
Output: a single line showing the volume in the n buckets seperated by spaces.
Example:
Input:
2 2
1 1
1 2
Output:
2 1
Constraints:
0 <= t <= 104; 1 <= n <= 105
I tried this problem. But I use O(n*t) algorithm. I increment each time the bucket from i to j at each step. But this shows time limit error. Is there any efficient algorithm to solve this problem. A small hint would suffice.
P.S: I have used C++ and Java as tags bcoz the program can be programmed in both the languages.
Instead of remembering the amount of water in each bucket, remember the difference between each bucket and the previous one.
have two lists of the intervals, one sorted by upper, one by lower bound
then iterate over n starting with a volume v of 0.
On each iteration over n
check if the next interval starts at n
if so increase v by one and check the next interval.
do the same for the upper bounds but decrease the volume
print v
repeat with the next n
I think the key observation here is that you need to figure out a way to represent your (possibly) 105 buckets without actually allocating space for each and every one of them, and tracking them separately. You need to come up with a sparse representation to track your buckets, and the water inside.
The fact that your input comes in ranges gives you a good hint: you should probably make use of ranges in your sparse representation. You can do this by just tracking the buckets on the ends of each range.
I suggest you do this with a linked list. Each list node will contain 2 pieces of information:
a bucket number
the amount of water in that bucket
You assume that all buckets between the current bucket and the next bucket have the same volume of water.
Here's an example:
Input:
5 30
1 5
4 20
7 13
25 30
19 27
Here's what would happen on each step of the algorithm, with step 1 being the initial state, and each successive step being what you do after parsing a line.
1:0→NULL (all buckets are 0)
1:1→6:0→NULL (1-5 have 1, rest are 0)
1:1→4:2→6:1→21:0→NULL (1-3 have 1, 4-5 have 2, 6-20 have 1, rest have 0)
1:1→4:2→6:1→7:2→14:1→21:0→NULL
1:1→4:2→6:1→7:2→14:1→21:0→25:1→NULL
1:1→4:2→6:1→7:2→14:1→19:2→21:1→25:2→28:1→NULL
You should be able to infer from the above example that the complexity with this method is actually O(t2) instead of O(n×t), so this should be much faster. As I said in my comment above, the bottleneck this way should actually be the parsing and output rather than the actual computation.
Here's an algorithm with space and time complexity O(n)
I am using java since I am used to it
1) Create a hashset of n elements
2) Each time a watering is made increase the respective elements count
3) After file parsing is complete then iterate over hashset to calculate result.
I am looking for a clear explanation to my question (NOT looking for code), but if a bit of code helps to explain yourself, then please do.. thank you :)
Question:
-using Java
-Main class asks user for 2 integer inputs, then places them into 2 arraylists, of type integer. Each digit is broken up and stored in its own index, so it is its own "element", so to speak.
For example, with my code right now, it goes something like this:
"Please enter an integer:"
688
"Please enter another integer:"
349
At this point now, internally, I have stored the input as 2 arraylists, that look like this:
ArrayList1: [6, 8, 8]
ArrayList2: [3, 4, 9]
Now, lets say I want to perform some addition, such as ArrayList1 + ArrayList2.
I'll probably go ahead and create a temporary 'result' arraylist, then move that answer over to arraylist1 when my calculation is complete.
But the part I am having trouble with, is coming up with a systematic clear way to add the arraylists together. Keep in mind that this example uses an arraylist which represents an integer of length 3, but this could be anything. I could, for example, have an arraylist with 50 elements, such as [2, 4, 4, 3, 7, 3, 6, 3,.............] which could represent a huge number in the trillions, etc.
Think about how you would do grade-school addition. You'd start up by lining up the numbers like this:
1 3 7
+ 4 5
-----------
Then, you'd add the last two digits to get
1 3 7
+ 4 5
-----------
2
And you'd have a carry of 1. You then add the next two digits, plus the carry:
1 3 7
+ 4 5
-----------
8 2
Now you have carry 0, so you can add the last digit and the missing digit to get
1 3 7
+ 4 5
-----------
1 8 2
The general pattern looks like this: starting from the last digit of each array, add the last two numbers together to get a sum and a carry. Write the units digit of the sum into the resulting array, then propagate the carry to the next column. Then add the values in that column (plus the carry) together, and repeat this process across the digits. Once you have exhausted all of the digits in one of the numbers, continue doing the sum, but pretend that there's a 0 as the missing digit. Once you have processed all the digits, you will have the answer you're looking for.
Hope this helps!
If you store digits backwards, your arrays will be much easier to manipulate, because their ones, tens, hundreds, etc. will be aligned with each other (i.e. they will be sitting at the same index).
You could then implement the addition the same way they teach in the elementary school: go through arrays of digits one by one, add them, check for digit overflow (>=10), and pay attention to the carry flag (result digit is (a+b) % 10, carry flag is (a+b)/10). If the carry flag is not zero when you are done with the addition, and there are no additional digits remaining on either side, add the carry flag to the end of the result array.
The only remaining issue is displaying the lists. You can do it with a simple backward loop.
P.S. If you would like to double-check your mulch-trilion calculation against something that is known to work, use BigInteger to compute the expected results, and check your results against theirs.
Think of an arraylist as a storage container. It can hold items in it that are of type "integer", but it's type is still "storage container". You can't perform math on these type of objects--only their contents.
you have
list1
list2
and need an extra variable
int carry
then
1 do add(0,0) on short list, so that at the end two lists have same length.
2 reversely loop the two list.
sum=(carry+(e1+e2))
set e1 (list1 element) = sum%10,
carry = sum/10,
till the first element.
3 if carry==1, list1.add(0,1)
now list1 stores the result.
Note, step1 is not a must. it could be done in loop by checking the short list's length.
I'm trying to program a multiple players game in Java.
I need to create a list of all combinations and to store these in an array.
If 2 players are logged in as the game start, the combinations are:
p1,p2 and p2, p1 (positions are important)
while if 3 players logged in to the game, the combinations are:
p1,p2,p3 ; p1,p3,p2 ; p2,p1,p3 ; p2,p3,p1 ; p3,p1,p2 and p3,p2,p1
In fact, I need a redundant array:
if 3 players are logged in, I need in advance the combinations of 3 AND the combinations of each possible pairs
p1,p2,p3 ; p1,p3,p2 ; p2,p1,p3 ; p2,p3,p1 ; p3,p1,p2 and p3,p2,p1
and
p1,p2 and p2, p1
and
p1,p3 and p3, p1
and
p2,p3 and p3, p2
)
Many players (EDITED: up to 8 players) may be logged in simultaneously to the same round of the game. (EDITED: there are up to 32 groups, but this is not important, because groups are independent)
Is there a quick, short and a simple way to create this combinations array for n players?
A recursive solution is foreseen and acceptable.
Many thanks
P.S.
My ongoing idea is to split the group into 2, a selected pair and the rest of the players.
The sekected pairs are selected using 2 FOR loops and the rest with a third.
If there are 2 players, no 'rest". If there are 3 players, the 2 FORs will select the positions of the pair and the rest will get the rest.
then, the rest are ordered using the same split procedure.
May this way get real? how? Will it be efficient?
Thanks again.
The number of permutations of size n is n!, which grows exponentially.
For example, the number of all permutations of 20 elements is 2432902008176640000(~2.43290201 × 10^18), quite big number.
Like you correctly guessed, there is a recursive algorithm for generating all permutations, but it is quite ineffecient in both time and space for reasons listed above.
However, if your task is generating a random permutation, an efficient algorithm does exist: Fisher–Yates shuffle. It requires O(n) time(assuming you can generate a random integer in O(1)), and O(1) of additional memory.
You know the number of entries in each array. For the array with all players, it's 256! That's possibilities for the first entry in the array, 255 for the next, and so forth. 256! is a larger enough number that my calculator can't handle it. Even for 170 players, the size of the array would be 1.3e241. Even on a 64 bit computer, you only have 1.8e19 addressable bytes. This basically means you need to rethink your approach.
I have two list of numbers, for every member of the second one I must tell if it's obtainable using all the numbers of the first one and placing '+' or '*' and as many '(' ')' I want.
I can't change the order .
List1 can contain a max of 20 elements beetween 1 and 100.
List2 can contain max 5 elements beetween 1 and 20'000.
EX:
List1=[2 4 3 5]
List2=[19 15 24]
19-> 2+(4*3)+5 YES
15 NO
24->2*(4+3+5) YES
With brute force it takes ages to handle inputs with List1 larger than 10.
edit: numbers are always positive.
edit:
I find the max and min numbers that are obtainable from the list and then I discard all the possibilities that have the target outside this range, then I try all the remaining ones.
MAX=n1*n2*n3*....*ni if there are 1 thei r added to their smallest neighbour
MIN=n1+n2+....+ni 1 excluded
Still it's not fast enough when input are big (List1 longer than 10 or numbers in List2 bigger than 10000)
For each sublist of List1, compute the numbers between 1 and 20,000 that can be made with that sublist. The resulting DP bears resemblance to CYK.
I'm being somewhat vague here because this is almost certainly a programming contest problem.
#u mad is correct, but I'll give a little more detail.
Suppose that n = size of list 1. For each 0 <= i < j < n you need to compute all of the distinct values in the range (1..20_000) that can be made from the numbers in the interval [i, j-1]. You can do this with recursion and memoization.
Once you've done this then the problem is easy.
You could try a smart brute force which discards sets of equations by chunks.