Google Code Jam 2011 is off to a huge start, with record-setting numbers across the board: we had a 10,336 qualifiers, out of 14,397 people who downloaded at least one input and 21,940 people who logged into the dashboard. Our contestants hailed from 130 different countries, and used 62 languages, though we aren't sure we'd recommend all of them in later rounds. This year there seems to be something of a competition to see who can use the most programming languages; contestant foxlit is tracking them on his site at http://www.go-hero.net/jam/11/multilang (warning: not all programming languages have family-friendly names).
We hope that you enjoyed the problems. Many contestants noticed that three of them had references to games. That wasn't planned; the judges are just playful people by nature.
Cast
Problem A. Bot Trust Written and prepared by David Arthur.
Problem B. Magicka Written and prepared by Bartholomew Furrow.
Problem C. Candy Splitting Written and prepared by Onufry Wojtaszczyk and Jorge Bernadas Saragoza.
Problem D. GoroSort Written and prepared by Igor Naverniouk.
Contest analysis presented by David Arthur, Bartholomew Furrow and Petr Mitrichev.
Solutions and other problem preparation by Patrick Nguyen, Kuang-che Wu, Cosmin Negruseri, Luka Kalinovcic, Greg Tener and Tomek Czajka.
Blue and Orange are friendly robots. An evil computer mastermind has locked them up in separate hallways to test them, and then possibly give them cake.
Each hallway contains 100 buttons labeled with the positive integers {1, 2, ..., 100}. Button k is always k meters from the start of the hallway, and the robots both begin at button 1. Over the period of one second, a robot can walk one meter in either direction, or it can press the button at its position once, or it can stay at its position and not press the button. To complete the test, the robots need to push a certain sequence of buttons in a certain order. Both robots know the full sequence in advance. How fast can they complete it?
For example, let's consider the following button sequence:
O 2, B 1, B 2, O 4
Here, O 2
means button 2 in Orange's hallway, B 1
means button 1 in Blue's hallway, and so on. The robots can push this sequence of buttons in 6 seconds using the strategy shown below:
Time | Orange | Blue -----+------------------+----------------- 1 | Move to button 2 | Stay at button 1 2 | Push button 2 | Stay at button 1 3 | Move to button 3 | Push button 1 4 | Move to button 4 | Move to button 2 5 | Stay at button 4 | Push button 2 6 | Push button 4 | Stay at button 2
Note that Blue has to wait until Orange has completely finished pushing O 2
before it can start pushing B 1
.
The first line of the input gives the number of test cases, T. T test cases follow.
Each test case consists of a single line beginning with a positive integer N, representing the number of buttons that need to be pressed. This is followed by N terms of the form "Ri Pi" where Ri is a robot color (always 'O' or 'B'), and Pi is a button position.
For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the minimum number of seconds required for the robots to push the given buttons, in order.
1 ≤ Pi ≤ 100 for all i.
Memory limit: 1GB.
1 ≤ T ≤ 20.
1 ≤ N ≤ 10.
Time limit: 30 seconds.
1 ≤ T ≤ 100.
1 ≤ N ≤ 100.
Time limit: 60 seconds.
3 4 O 2 B 1 B 2 O 4 3 O 5 O 8 B 100 2 B 2 B 1
Case #1: 6 Case #2: 100 Case #3: 4
Magicka™ is an action-adventure game developed by Arrowhead Game Studios. In Magicka you play a wizard, invoking and combining elements to create Magicks. This problem has a similar idea, but it does not assume that you have played Magicka.
Note: "invoke" means "call on." For this problem, it is a technical term and you don't need to know its normal English meaning.
As a wizard, you can invoke eight elements, which are the "base" elements. Each base element is a single character from {Q, W, E, R, A, S, D, F}. When you invoke an element, it gets appended to your element list. For example: if you invoke W and then invoke A, (we'll call that "invoking WA" for short) then your element list will be [W, A].
We will specify pairs of base elements that combine to form non-base elements (the other 18 capital letters). For example, Q and F might combine to form T. If the two elements from a pair appear at the end of the element list, then both elements of the pair will be immediately removed, and they will be replaced by the element they form. In the example above, if the element list looks like [A, Q, F] or [A, F, Q] at any point, it will become [A, T].
We will specify pairs of base elements that are opposed to each other. After you invoke an element, if it isn't immediately combined to form another element, and it is opposed to something in your element list, then your whole element list will be cleared.
For example, suppose Q and F combine to make T. R and F are opposed to each other. Then invoking the following things (in order, from left to right) will have the following results:
Given a list of elements to invoke, what will be in the element list when you're done?
The first line of the input gives the number of test cases, T. T test cases follow. Each test case consists of a single line, containing the following space-separated elements in order:
First an integer C, followed by C strings, each containing three characters: two base elements followed by a non-base element. This indicates that the two base elements combine to form the non-base element. Next will come an integer D, followed by D strings, each containing two characters: two base elements that are opposed to each other. Finally there will be an integer N, followed by a single string containing N characters: the series of base elements you are to invoke. You will invoke them in the order they appear in the string (leftmost character first, and so on), one at a time.
For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1) and y is a list in the format "[e0, e1, ...]" where ei is the ith element of the final element list. Please see the sample output for examples.
1 ≤ T ≤ 100.
Each pair of base elements may only appear together in one combination, though they may appear in a combination and also be opposed to each other.
No base element may be opposed to itself.
Unlike in the computer game Magicka, there is no limit to the length of the element list.
Memory limit: 1GB.
0 ≤ C ≤ 1.
0 ≤ D ≤ 1.
1 ≤ N ≤ 10.
Time limit: 30 seconds.
0 ≤ C ≤ 36.
0 ≤ D ≤ 28.
1 ≤ N ≤ 100.
Time limit: 60 seconds.
5 0 0 2 EA 1 QRI 0 4 RRQR 1 QFT 1 QF 7 FAQFDFQ 1 EEZ 1 QE 7 QEEEERA 0 1 QW 2 QW
Case #1: [E, A] Case #2: [R, I, R] Case #3: [F, D, T] Case #4: [Z, E, R, A] Case #5: []
Magicka™ is a trademark of Paradox Interactive AB. Paradox Interactive AB does not endorse and has no involvement with Google Code Jam.
Sean and Patrick are brothers who just got a nice bag of candy from their parents. Each piece of candy has some positive integer value, and the children want to divide the candy between them. First, Sean will split the candy into two piles, and choose one to give to Patrick. Then Patrick will try to calculate the value of each pile, where the value of a pile is the sum of the values of all pieces of candy in that pile; if he decides the piles don't have equal value, he will start crying.
Unfortunately, Patrick is very young and doesn't know how to add properly. He almost knows how to add numbers in binary; but when he adds two 1s together, he always forgets to carry the remainder to the next bit. For example, if he wants to sum 12 (1100 in binary) and 5 (101 in binary), he will add the two rightmost bits correctly, but in the third bit he will forget to carry the remainder to the next bit:
1100 + 0101 ------ 1001
So after adding the last bit without the carry from the third bit, the final result is 9 (1001 in binary). Here are some other examples of Patrick's math skills:
5 + 4 = 1 7 + 9 = 14 50 + 10 = 56
Sean is very good at adding, and he wants to take as much value as he can without causing his little brother to cry. If it's possible, he will split the bag of candy into two non-empty piles such that Patrick thinks that both have the same value. Given the values of all pieces of candy in the bag, we would like to know if this is possible; and, if it's possible, determine the maximum possible value of Sean's pile.
The first line of the input gives the number of test cases, T. T test cases follow. Each test case is described in two lines. The first line contains a single integer N, denoting the number of candies in the bag. The next line contains the N integers Ci separated by single spaces, which denote the value of each piece of candy in the bag.
For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1). If it is impossible for Sean to keep Patrick from crying, y should be the word "NO". Otherwise, y should be the value of the pile of candies that Sean will keep.
1 ≤ T ≤ 100.
1 ≤ Ci ≤ 106.
Memory limit: 1GB.
2 ≤ N ≤ 15.
Time limit: 30 seconds.
2 ≤ N ≤ 1000.
Time limit: 60 seconds.
2 5 1 2 3 4 5 3 3 5 6
Case #1: NO Case #2: 11
Goro has 4 arms. Goro is very strong. You don't mess with Goro. Goro needs to sort an array of N different integers. Algorithms are not Goro's strength; strength is Goro's strength. Goro's plan is to use the fingers on two of his hands to hold down several elements of the array and hit the table with his third and fourth fists as hard as possible. This will make the unsecured elements of the array fly up into the air, get shuffled randomly, and fall back down into the empty array locations.
Goro wants to sort the array as quickly as possible. How many hits will it take Goro to sort the given array, on average, if he acts intelligently when choosing which elements of the array to hold down before each hit of the table? Goro has an infinite number of fingers on the two hands he uses to hold down the array.
More precisely, before each hit, Goro may choose any subset of the elements of the array to freeze in place. He may choose differently depending on the outcomes of previous hits. Each hit permutes the unfrozen elements uniformly at random. Each permutation is equally likely.
The first line of the input gives the number of test cases, T. T test cases follow. Each one will consist of two lines. The first line will give the number N. The second line will list the N elements of the array in their initial order.
For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1) and y is the expected number of hit-the-table operations when following the best hold-down strategy. Answers with an absolute or relative error of at most 10-6 will be considered correct.
1 ≤ T ≤ 100;
The second line of each test case will contain a permutation of the N
smallest positive integers.
Memory limit: 1GB.
1 ≤ N ≤ 10;
Time limit: 30 seconds.
1 ≤ N ≤ 1000;
Time limit: 60 seconds.
3 2 2 1 3 1 3 2 4 2 1 4 3
Case #1: 2.000000 Case #2: 2.000000 Case #3: 4.000000
BAM! Robots gave us 6 extra seconds of cooperation. Good job, robots!
-- Cave Johnson (Portal 2)
Hopefully your robots were more focused on teamwork than Cave Johnson's were, or you would never get all the buttons pressed. Just be glad there were no mashy spike plates or potatoes to contend with! Perhaps in the finals...
Anyway, if you think about this problem from the perspective of a single robot, the strategy should be pretty intuitive: always move towards the next button and then push it as soon as it comes up in the sequence.
So the most natural solution to this problem is a straight simulation:
At most 100 buttons needs to be pressed altogether and the distance between buttons is at most 100, so this solution will run plenty fast.
If you get stuck on the implementation, remember that you can see other contestants' source code. There is no better way to learn!
This problem can be solved with a simulation. First, we have to remember what elements combine to make other elements. A map of some sort, like a hash map, is a great way of doing this. Next we have to track the opposed elements, remembering that one element can be opposed to multiple other elements; a set of pairs, while not particularly efficient for this purpose, will do the trick.
Finally, the simulation itself. For each character, first we check to see if it combines with the last item on the element list, and combine it if so. If it doesn't combine, then we iterate through the elements already in the list and see if it's opposed to any of them -- if so, we clear the list. Finally, if neither of those conditions was met, we append it to the list. Here is some Pythonesque pseudocode that solves the problem:
# Let combo_list contain all the combinations as 3-letter strs. # Let opposed_list contain all the opposed elements as 2-letter strs. # Let invoke be a str containing the elements to invoke. combos = dict() opposed = dict() for x in combo_list: combos[x[0] + x[1]] = x[2] combos[x[1] + x[0]] = x[2] for x in opposed_list: opposed.add(x[0] + x[1]) opposed.add(x[1] + x[0]) # Now combos contains a mapping from each pair to the thing it # creates. If one of the combinations was "ABC", then # combos["AB"] = "C" and combos["BA"] = "C". # opposed is filled in a similar way. element_list = [] for element in invoke: # If element_list isn't empty, the last element might combine # with the element being invoked. if element_list: last_two = element_list[-1] + element if last_two in combos: element_list[-1] = combos[last_two] continue # Now we iterate through element_list to see if anything there # is opposed to the element being invoked. wipe_list = False for e in element_list: if (e + element) in opposed: wipe_list = True if wipe_list: element_list = [] continue # There was no combination and no erasing: just append the # element to the list. element_list.append(element)
The main step needed to solve this problem is to understand Patrick's strange addition algorithm. For example, can we describe what happens when Patrick adds up several numbers instead of just two? It turns out we can: we should write all numbers in binary, align them by their least significant bit, and write 1 in those positions where we have an odd number of 1 bits in the summands (the numbers being added).
Consider this example: suppose Patrick needs to add 5, 7 and 9 together. First, he adds up 5 and 7 by writing them in binary and adding digit-by-digit without carry, as described in the problem statement:
101 + 111 ----- 010
The result is 010 in binary, which is 2. Now, he adds up 2 and 9:
0010 + 1001 ------ 1011
The result is 1011 in binary, which is 11. It is most instructive to look at what happened to the least significant bit: after adding up two of the numbers, we had a 0 in the least significant bit since both of the summands had a 1 there. However, we have a 1 in the least significant bit of the overall result since the third number had a 1 there as well. It's not hard to see that this generalizes as described above: for any bit, it will be equal to 1 in the overall sum if and only if this bit is set to 1 in an odd number of summands.
Having established that, we can now understand Sean's task better. He needs to separate the given set of numbers into two parts in such a way that for every bit position, either:
But saying that we need two numbers to be either both odd, or both even, is equivalent to saying that their sum must be even!
That allows us to reformulate Sean's task simply as: he needs to separate the given set of numbers into two parts in such a way that for every bit position, an even number of summands have the bit set to 1 across both parts put together. Suddenly, we understand that this condition doesn't rely on the way we separate the numbers into two parts at all! Either it is true for every bit position that an even number of all summands have the bit set to 1, in which case any separation into two non-empty piles will make Patrick happy, or there is some bit which is 1 in an odd number of summands, in which case there's no way to make Patrick happy.
For example, suppose Sean has pieces of candy with values 5, 7, 9 and 11. If he separates them into 5 and 7 for himself, and 9 and 11 for Patrick, Patrick will add 5 and 7 as 5+7=1012+1112=0102=2, and 9 and 11 as 9+11=10012+10112=00102=2, so Patrick is happy. But even if Sean takes 7, 9 and 11 and leaves just 5 to Patrick, Patrick will add 7, 9 and 11 as 7+9+11=01112+10012+10112=01012=5, so he is still happy! It's not difficult to verify that in all other cases Patrick is happy as well.
All the above reasoning can be made simpler if you notice that Patrick's strange addition is exactly bitwise exclusive or. The condition for Patrick's happiness can be reformulated as the bitwise exclusive or of all candy values being equal to zero. In many programming languages, bitwise exclusive or is already built in with the "^" operator, making this very easy to check!
Now, how does the overall solution for the problem work? First, we need to check if Patrick will be happy - as shown above, this does not depend on Sean's piles. If not, then we just output "NO" for this testcase. If yes, then Sean should maximize his pile, and this is achieved by taking all pieces of candy except the one with the smallest value.
This problem is very mathematical in nature, requiring a lot of thought and only a little code to solve correctly. We put it as a problem on the Qualifying Round to give you something different to try without having to worry about time pressure or advancement. We hope you enjoyed it!
For an arbitrary array A, let n(A) be the number of elements that are not already in the correct position. It turns out that the answer you are looking for is simply n(A). Once you realize this, it is easy to calculate with a simple loop, but how do you prove it?
Let's first show that the expected number of hits is never more than n(A). Suppose Goro always holds down only those elements that are already in position, and then he randomly permutes the rest. Let x(A) be the expected number of hits required for him to sort A using this strategy.
Lemma: x(A) = n(A) for all A.
We prove this by induction on n(A). If n(A) = 0, then the array is already sorted, and we're done. To set up the induction, let's suppose we have proven the lemma already for smaller values of n(A) and we are now trying to prove it for A. Let pt be the probability that exactly t elements are still out of position after the first hit, and let x't be the expected number of hits required in this case. We make three observations:
Now let's write down a formula for x(A):
1 + p0 * x'0 + p1 * x'1 + ... + pN * x'N
= 1 + p0 * 0 + p1 * 1 + ... + pN * N + pN * (x(A) - N)
= N + pN * (x(A) - N),
which simplifies to (N - x(A)) * (1 - pN) = 0. Since pN < 1, we must have x(A) = N, and the lemma is proven.
To complete the proof, we need to calculate y(A), the expected number of hits required for Goro to sort A if he uses the (still unknown) optimal strategy. Since y(A) ≤ x(A) by definition, we have already proven y(A) ≤ n(A).
To conversely prove n(A) ≤ y(A), it would be nice to just extend the proof of the previous lemma. There is one big technical issue though: it is possible for n(A) to go up if Goro doesn't hold down enough elements, and so it is tricky to set up an induction on n(A). We'll resolve this by having a separate proof for this part, and this time use a slightly different induction hypothesis. We can then follow the previous argument very closely.
Lemma 2: Let K be a non-negative integer. Then for any k ≤ K, the statement y(A) = k is equivalent to the statement n(A) = k.
We will prove this by induction on K. Both y(A) = 0 and n(A) = 0 are equivalent to the array already being sorted, so the K = 0 case is clear. Now, let's suppose we have proven the lemma for K already, and are trying to prove it for K+1. Choose A such that y(A) is the smallest possible value larger than K and consider the optimal strategy for Goro. Let T be the number of elements that are either (a) not in the correct position in A, or (b) permuted when Goro hits the table. Define pi and x'i as we did before. Note that T ≥ n(A) ≥ K+1 by the inductive hypothesis.
As in the previous lemma, we can now prove the following:
As before, we can now write y(A) as
1 + p0 * x'0 + p1 * x'1 + ... pT * x'T
≥ 1 + (p0 * 0 + p1 * 1 + ... + pT * T) + (pK+1 + pK+2 + ... + pT) * (y(A) - T)
≥ T + (pK+1 + pK+2 + ... + pT) * (y(A) - T)
which simplifies to (y(A) - T) * (1 - pK+1 - ... - pT) ≥ 0. The second term has to be positive (if not, then y(A) ≥ min(x'K+1, x'K+2, ...) + 1, which contradicts the third bullet point above is therefore impossible), so we must have y(A) ≥ T ≥ n(A) ≥ K+1. Equality holds only if n(A) = K+1. The first lemma guarantees y(A) ≤ x(A) ≤ K+1 in this case, and the proof is complete!